【问题标题】:javascript: 10 x speedup via loop inline?javascript:通过循环内联加速 10 倍?
【发布时间】:2012-07-15 06:26:09
【问题描述】:

我遇到了一个性能问题,我的内部 javascript 行为异常 火狐 (13.0.1)。最新的 Chrome 显示相同的行为。

当我执行我的 javascript 代码时,它看起来像 下面的代码sn-p,结果很慢。 但是,如果我简单地内联 'j' 上的外循环。对于我的示例应用程序,这意味着我 简单地分别为'j = 0'和'j = 1'的固定值写两次,因为'm'等于2。当然,我不想要'm' 被硬编码,所以我问自己究竟是什么导致了这种减速 使用真正的循环?

有人有想法吗?

我在网络工作者中运行代码。奇怪的是,如果我在主 javascript 上下文中执行相同的内容,而不是在工作人员的上下文中执行内联,则不会出现内联的积极影响。尽管如此,只为一个 'j' 值执行循环内容在所有情况下都会带来巨大的加速帮助。这是否也与内存管理有关?

提前非常感谢!

//m: very small, 1-2
for (j = 0; j < m; ++j) {
  var attrib = attributes[j];

  //n: very large, ~3*10^6 elements
  for (i = 0; i < n; ++i) {

    var data = largeBuffer[i];

    //nc: very small, 2-3
    for (c = 0; c < nc; ++c) {
      var component;
      //compute 'component
      //..
      attrib.typedArray[baseIdx + c] |= component;
    }

    baseIdx += nc;
  }
}

【问题讨论】:

  • 您知道,您所做的一般做法称为“loop unwinding”。 (链接的 Wikipedia 页面提到了速度优势,但这些可能不足以解释为什么您只看到了巨大的加速;您的案例可能与 JS 特定的内部结构有关。)
  • 您是否需要使用 Javascript 在客户端机器上处理大约 10+ 百万个项目?听起来 Javascript 需要做很多工作——这个过程可以重组并在其他地方完成吗?有趣的是,它在做什么?
  • 它是解压数据,所以理论上这个过程可以分成几个“块”(nczonline.net/blog/2009/01/13/speed-up-your-javascript-part-1)。我当前实验中的数据大小约为 n 的 300 万个元素(参见示例代码)。
  • (...并且每个数据元素都有几个(2-3)个组件,因此总共有超过1000万个元素被处理)
  • 我明白了,我可以看到你在 Javascript 中从哪里来。是 JSON 数据吗?您真的需要所有这些数据吗?用户真的会查看所有数据吗?如果用户需要,您可以只返回部分数据并获取其余数据吗?

标签: javascript performance memory


【解决方案1】:

这只是一个假设。我不太了解JS解释器的内部结构。

也许当您内联外循环时,解释器会看到 4 次相同的代码,从而触发 JIT。相反,当您使用常规循环时,JIT 只能看到一次代码。

再一次,这只是一个假设。

【讨论】:

  • 是的,我想到了类似的东西...也许 Js + Firefox + JIT 是一组很好的搜索关键字,所以非常感谢您的启发 ;-) 我的主要问题观点是缺乏对 JS 组件内部真正发生的事情的理解,这使得编写高效的代码非常困难......我已经向 Mozilla 的 dev-tech-js-engine 列表发送了一封邮件 4 天之前,但没有得到回应,所以任何关于此类帮助资源的提示仍然非常感谢。
  • @Var 在这篇博文中:blog.mrale.ph/post/24351748336/explaining-js-vm-in-js 一个人试图在... JS 中实现一个 JS 解释器。这是了解其工作原理的良好开端。