2

I have a browser-based visualization app where there is a graph of data points, stored as an array of objects:

data = [
    {x: 0.4612451, y: 1.0511} , 
    ... etc
]

This graph is being visualized with d3 and drawn on a canvas (see that question for an interesting discussion). It is interactive and the scales can change a lot, meaning the data has to be redrawn, and the array needs to be iterated through quite frequently, especially when animating zooms.

From the back of my head and reading other Javascript posts, I have a vague idea that optimizing dereferences in Javascript can lead to big performance improvements. Firefox is the only browser on which my app runs really slow (compared to IE9, Chrome, and Safari) and it needs to be improved. Hence, I'd like to get a firm, authoritative answer the following:

How much slower is this:

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

compared to this:

// 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 and ys are d3 scale objects, they are functions that compute the scaled positions. I mentioned the above that the above code may need to run up to 60 frames per second and can lag like balls on Firefox. As far as I can see, the only differences are array dereferences vs object accessing. Which one runs faster and is the difference significant?

4

2 回答 2

3

这些循环优化中的任何一个都不太可能产生任何影响。通过这样的循环2000次根本不算多。

我倾向于怀疑canvas.arc()在 Firefox 中实现缓慢的可能性。您可以通过替换canvas.lineTo()我知道在 Firefox 中快速的调用来测试这一点,因为我在我的PolyGonzo地图中使用了它。该页面上测试地图上的“所有 3199 个县”视图绘制了 3357 个多边形(有些县有多个多边形),总共 33,557 个点,并且它为每个点循环通过一个类似的画布循环。

于 2013-03-27T00:03:27.543 回答
0

感谢 JsPerf 的建议,我实现了一个快速测试。如果其他人在这里添加他们的结果,我将不胜感激。

http://jsperf.com/canvas-dots-testing:截至 2013 年 3 月 27 日的结果:

在此处输入图像描述

到目前为止,我观察到以下情况:

  • 数组或对象是否更好似乎取决于浏览器和操作系统。例如,Chrome 在 Linux 上的速度相同,但对象在 Windows 上更快。但对于许多人来说,它们几乎是相同的。
  • Firefox 只是其中的乌龟,这也有助于证实 Michael Geary 的假设,即它canvas.arc()只是超级慢。
于 2013-03-27T00:38:01.467 回答