【问题标题】:Performance concerns when storing data in large arrays with Javascript使用 Javascript 将数据存储在大型数组中时的性能问题
【发布时间】:2013-03-16 23:37:57
【问题描述】:

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

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 上像球一样滞后。据我所知,唯一的区别是数组取消引用与对象访问。哪一个跑得更快,差异显着?

【问题讨论】:

  • 你应该在尽可能多的浏览器中测试它,比如jsperf。任何一个上最快的都可能不是另一个上最快的(例如,在大多数浏览器中,递减 while 循环曾经比递增 for 循环快,除了 Opera,它们的速度要慢得多),所以你可能需要妥协。
  • 一些var 声明dcxcy 可能吗?关于“哪个跑得快”:只能test, test, test
  • 抱歉,coffeescript 的翻译错误。我的世界里没有变量。已修复,谢谢。
  • xsys 函数是什么?他们最好是内联的吗?

标签: javascript arrays performance javascript-objects


【解决方案1】:

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

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

【讨论】:

  • 我正在画一个圆圈,所以我不确定canvas.lineTo() 会有什么帮助。
  • 这是一个缩小问题范围的测试。 canvas.lineTo() 不会帮你画圆。它将帮助您找出在尝试优化循环结构时是否在寻找错误的树。如果当您使用canvas.lineTo() 时它变得更快,那么您就知道问题出在Firefox 对canvas.arc() 的实现中。相反,如果.lineTo() 仍然很慢,那么您知道我对.arc() 的怀疑是错误的。也就是说,它可能无法帮助您加快速度,但它会帮助您了解问题所在。
  • 是的,你是对的。它是canvas.arc()。 >.
  • 我想尝试的一件事可能是 WebGL 而不是 Canvas?不过,您仍然需要为其他浏览器支持 Canvas。 developer.mozilla.org/en-US/docs/DOM/HTMLCanvasElementkhronos.org/registry/webgl/specs/latest
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2010-12-24
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多