使用Javascript在大型数组中存储数据时的性能问题

时间:2013-03-26 23:50:37

标签: javascript arrays performance javascript-objects

我有一个基于浏览器的可视化应用程序,其中有一个数据点图表,存储为对象数组:

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);
}

xsys是d3比例对象,它们是计算缩放位置的函数。我上面提到上面的代码可能需要运行每秒60帧,并且可以像Firefox上的球一样滞后。据我所知,唯一的区别是数组解引用与对象访问。哪一个运行得更快,差异显着?

2 个答案:

答案 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日的结果:

enter image description here

到目前为止,我已经观察到以下内容:

  • 数组或对象是否更好似乎取决于浏览器和操作系统。例如,Chrome在Linux上的速度相同,但Windows中的对象速度更快。但对于许多人来说,他们几乎完全相同。
  • Firefox只是乌龟之一,这也有助于确认Michael Geary的假设,canvas.arc()只是超级慢。