问题
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?
回答1:
It's pretty unlikely that any of these loop optimizations will make any difference. 2000 times through a loop like this is not much at all.
I tend to suspect the possibility of a slow implementation of canvas.arc()
in Firefox. You could test this by substituting a canvas.lineTo()
call which I know is fast in Firefox since I use it in my PolyGonzo maps. The "All 3199 Counties" view on the test map on that page draws 3357 polygons (some counties have more than one polygon) with a total of 33,557 points, and it loops through a similar canvas loop for every one of those points.
回答2:
Thanks to the suggestion for JsPerf, I implemented a quick test. I would be grateful for anyone else to add their results here.
http://jsperf.com/canvas-dots-testing: results as of 3/27/13:
I have observed the following so far:
- Whether arrays or objects is better seems to depend on the browser, and OS. For example Chrome was the same speed on Linux but objects were faster in Windows. But for many they are almost identical.
- Firefox is just the tortoise of the bunch and this also helps confirm Michael Geary's hypothesis that its
canvas.arc()
is just super slow.
来源:https://stackoverflow.com/questions/15649543/performance-concerns-when-storing-data-in-large-arrays-with-javascript