2013-03-26 24 views
2

存储在大的阵列的数据时,我有一个基于浏览器的可视化应用程序,其中有数据点的图表,存储作为对象的数组:性能关注的Javascript

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帧每秒和可以滞后像火球上的球。据我所见,唯一的区别是数组解引用vs对象访问。哪一个运行速度更快,差异显着?

+2

您应该在[jsperf](http://jsperf.com/)上对其进行测试,尽可能多地使用浏览器。在另一个上最快的可能不是最快的(例如,递减循环比在大多数浏览器中增加循环要快一些,除了Opera,它们相当慢),所以你可能需要妥协。 – RobG 2013-03-27 00:01:19

+1

'd','cx','cy'的一些'var'声明可能?在“*哪一个跑得快*”:你只能[测试,测试,测试](http://jsperf.com/) – Bergi 2013-03-27 00:01:48

+0

对不起,从coffeescript翻译错误。我的世界没有变数。修正并感谢。 – 2013-03-27 00:02:29

回答

3

这些循环优化中的任何一个都不会有什么不同。通过这样的循环2000次并不多。

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

+0

我正在画一个圆,所以我不确定'canvas.lineTo()'会如何帮助。 – 2013-03-27 00:04:39

+1

这是一个缩小问题的测试。 'canvas.lineTo()'不会帮你绘制一个圆圈。它将帮助您了解是否在试图优化循环结构时吠叫错误的树。如果在使用'canvas.lineTo()'的时候得到了很多快,那么你知道问题出在Firefox的'canvas.arc()'实现中。相反,如果它仍然与'.lineTo()'一样慢,那么你知道我对'.arc()'的怀疑是错误的。也就是说,它可能无法帮助你加快速度,但它会帮助你知道问题出在哪里。 – 2013-03-27 00:11:49

+0

是的,你是对的。它是'canvas.arc()'。 >。 2013-03-27 00:15:48

0

感谢JsPerf的建议,我实施了一个快速测试。我会很感激任何人在这里添加他们的结果。

http://jsperf.com/canvas-dots-testing:结果的13年3月27日:到目前为止

enter image description here

我观察到以下几点:

  • 无论数组或对象是更好似乎依赖于浏览器,和操作系统。例如,Chrome在Linux上的速度相同,但Windows中的对象速度更快。但是对于很多人来说他们几乎是一样
  • Firefox只是一群乌龟,这也有助于证实Michael Geary的假设,即它的canvas.arc()只是超级慢。