我有一个基于浏览器的可视化应用程序,其中有一个数据点图表,存储为对象数组:
data = [
{x: 0.4612451, y: 1.0511} ,
... etc
]
此图表为visualized with d3 and drawn on a canvas(有关讨论,请参阅该问题)。它是交互式的,并且比例可以改变很多,这意味着数据必须重新绘制,并且数组需要经常迭代,特别是在动画放大时。
从我的脑海中读到其他Javascript帖子,我有一个模糊的想法,即优化Javascript中的解引用可以带来很大的性能提升。 Firefox是我的应用程序运行速度非常慢的唯一浏览器(与IE9,Chrome和Safari相比),需要进行改进。因此,我想得到一个坚定,权威的答案如下:
这个慢多少:
// data is an array of 2000 objects with {x, y} attributes
var n = data.length;
for (var i=0; i < n; i++) {
var d = data[i];
// Draw a circle at scaled values on canvas
var cx = xs(d.x);
var cy = ys(d.y);
canvas.moveTo(cx, cy);
canvas.arc(cx, cy, 2.5, 0, twopi);
}
与此相比:
// data_x and data_y are length 2000 arrays preprocessed once from data
var n = data_x.length;
for (var i=0; i < n; i++) {
// Draw a circle at scaled values on canvas
var cx = xs(data_x[i]);
var cy = ys(data_y[i]);
canvas.moveTo(cx, cy);
canvas.arc(cx, cy, 2.5, 0, twopi);
}
xs
和ys
是d3比例对象,它们是计算缩放位置的函数。我上面提到上面的代码可能需要运行每秒60帧,并且可以像Firefox上的球一样滞后。据我所知,唯一的区别是数组解引用与对象访问。哪一个运行得更快,差异显着?
答案 0 :(得分:3)
这些循环优化中的任何一个都不太可能产生任何影响。通过像这样的循环2000次并不多。
我倾向于怀疑Firefox中canvas.arc()
执行速度慢的可能性。您可以通过替换我知道在Firefox中快速的canvas.lineTo()
调用来测试这一点,因为我在PolyGonzo地图中使用它。该页面上的测试地图上的“所有3199县”视图绘制了3357个多边形(一些县有多个多边形),共有33,557个点,并且它为每个点循环一个类似的画布循环。
答案 1 :(得分:0)
感谢JsPerf的建议,我实施了快速测试。我很感激其他人在这里添加他们的成果。
http://jsperf.com/canvas-dots-testing:截至2013年3月27日的结果:
到目前为止,我已经观察到以下内容:
canvas.arc()
只是超级慢。