Skip to content

性能 ​

Charturbo 把繁重的工作放在 WebAssembly 中完成,并把数据保留在 GPU 上,从而让缩放、平移和悬停保持在屏幕刷新率。本页说明速度从何而来、在大数据下如何保持,以及基准测试测量了什么。

基准测试对比

为什么快 ​

技术适用对象
在 Rust 中按像素列做 M4 降采样(每列的首个、末个、最小值和最大值)折线图和面积图:一百万个样本缩减为几千条线段,尖峰得以保留
按像素列聚合 OHLC宽度小于 2 px 的 K 线
GPU 实例化,点只上传一次散点图 / 气泡图:缩放和平移只改变视图
数值网格作为一张 R32Float 纹理,配合 256 色查找表最大 4096 × 4096 个单元格的热力图:只绘制一个四边形,更换色带无需重新上传
在 Rust 中完成命中检测、堆叠计算、刻度布局、层级与桑基图布局悬停和布局的开销不留在 JavaScript 中
只上传变化的部分数据流只上传降采样结果(1M 窗口每帧约 155 KB);桑基图悬停和矩形树图图例高亮只修改 uniform,而不是几何数据
常驻 GPU 的图布局(stepPhysicsAsync,WebGPU)位置和速度保留在 GPU 缓冲区中;由 GPU 构建 Barnes-Hut 八叉树并完成积分
DOM 只用于文本标题、图例、坐标轴标签和提示框;刻度标签 DOM 只在刻度变化时重建

大数据技巧 ​

传入类型化数组 ​

数值使用 Float32Array,x 值和时间戳使用 Float64Array。普通数组也可以,但会先被转换。只有一个系列且以 Float32Array(以及可选的 Float64Array x)传入时,SDK 会直接把数组交给引擎,而不生成拼接副本;在基准测试中,这让 1000 万个样本的折线所占 WebAssembly 内存从 78 MB 降到 41 MB。

ts
const values = new Float32Array(n);
const x = new Float64Array(n); // 时间轴使用 epoch ms
sdk.renderLineChart([{ name: '传感器', values, x }], { axes: { x: { type: 'time' } } });
sdk.render();

追加数据,而不是重新渲染 ​

appendSeriesData 向现有系列追加样本,maxPoints 维持一个滑动窗口。裁剪的均摊复杂度为 O(追加的样本数),下一帧只对可见范围重新降采样。堆叠面积图使用 appendAreaData 完成同样的事情。每次更新都用完整数据调用 renderLineChart 会重新复制全部数据。

ts
sdk.appendSeriesData(0, chunk, chunkX, { maxPoints: 1_000_000 });
sdk.render();

只在有变化时渲染 ​

没有空闲循环:render() 只绘制一帧。请在数据或视图变化后调用它,或在 enableNodeInteractions 中使用 autoRender: true。对于数据流,请合并更新,每个动画帧只渲染一次。

多个图表共享 GPU 设备 ​

Charturbo.create(canvas) 会为每个画布请求适配器和设备并编译所有管线,而浏览器把 WebGL 上下文限制在 16 个左右。使用 CharturboDevice 时,100 个迷你图的创建和首次渲染在 WebGPU 上耗时 165 ms,在 WebGL2 上耗时 717 ms(无头 Chrome)。参见共享 GPU 设备。

了解限制 ​

  • 散点图没有点降采样:每个点都会被绘制。500 万个点时,缩放和平移受 GPU 限制,为 12–13 fps。
  • 当图表的 staged 标记超过 50,000 个时(例如一百万个点的散点图),会跳过动画。
  • 10 万个节点的图物理模拟在 CPU 上无法实时运行。请先用 warmup() 完成布局后只做渲染,或降低步进频率,或在 WebGPU 上使用 stepPhysicsAsync。
  • 在 WebGL2 回退模式下,散点图、热力图和多系列图表的 WebAssembly 内存峰值高出 1.6–2.4 倍。

进行测量 ​

sdk.getRenderStats() 返回 GPU 缓冲区和纹理字节数、上一帧上传的字节数、staged 标记数量以及 WebAssembly 内存大小(在没有计数器的后端上返回 null)。

基准测试摘要 ​

使用 web/bench/ 测试框架在一台机器上测量:Apple M1,无头 Chrome 156,960 × 540 画布,DPR 1,60 Hz。稳态为 3 秒的滚轮缩放和拖拽平移(柱状图为悬停扫描)。在其他机器和浏览器上数值会有所不同。

场景TTFF ms WebGPU / WebGL2稳态帧 med / p95 / max ms丢失 vsync / 帧数每帧工作 med msGPU MB
line-1m-1s16.7 / 16.616.7 / 16.7 / 16.70/1801.70.7
line-10m-1s91.8 / 92.316.7 / 16.7 / 33.34/1762.90.7
area-stacked-1m26.9 / 25.616.7 / 16.7 / 33.31/1795.55.3
scatter-1m46.1 / 46.916.7 / 16.7 / 16.70/1801.232.7
scatter-5m210 / 24483.3 / 117 / 117144/371.6128.7
bar-10k19.0 / 19.116.7 / 16.7 / 16.70/1801.11.2
heatmap-409692.9 / 96.416.7 / 16.7 / 16.70/1801.364.7
candle-1m33.2 / 33.316.7 / 16.7 / 16.70/1801.60.7
stream-1m15.9 / 16.216.7 / 16.7 / 16.70/1803.20.7

TTFF 和帧时间按 16.7 ms 的 vsync 量化;16.7 表示“在一帧之内”。stream-1m 每帧向 1M 窗口追加 10k 个点。

图布局,3 秒稳态(2026-10-27,布局改为常驻 GPU 之前):

节点 / 边CPU 物理 ms / FPS混合 GPU 物理 ms / FPS
10k / 20k17.74 / 52.76.23 / 60.0
100k / 200k285.76 / 3.741.87 / 19.6

与其他库的对比(uPlot、ECharts、Chart.js、Plotly、ChartGPU、SciChart、Highcharts、three.js、deck.gl、cosmos.gl、3d-force-graph)、完整的测量方法和已知限制见基准测试方法。自行运行:cd web && npm run bench。

另请参阅 ​

MIT License