这个for循环是否多次迭代?

loc*_*ice 14 javascript performance

我一直在与同事讨论一些代码:

for(const a of arr) {
  if(a.thing)
    continue;
  // do a thing
}
Run Code Online (Sandbox Code Playgroud)

建议过滤这个并使用forEach

arr.filter(a => !a.thing)
  .forEach(a => /* do a thing */);
Run Code Online (Sandbox Code Playgroud)

有关迭代超过必要的讨论.我看了这个,我找不到任何东西.我也试图找出如何查看优化输出,但我不知道如何做到这一点.

我希望的是,filterforEach转成代码,很喜欢for ofcontinue,但我不知道如何可以肯定的.

我该怎么知道?到目前为止,我唯一尝试过的是谷歌.

Tra*_*s J 6

你的第一个例子(in for循环)是O(n),它将执行n次(n是数组的大小).

你的第二个例子(过滤器forEach)是O(n + m),它将在过滤器中执行n次(n是数组的大小),然后m次(m是过滤器后结果数组的大小)发生).

因此,第一个例子更快.然而,在没有非常大的样本集的这种类型的示例中,差异可能以微秒或纳秒来度量.

关于编译优化,这基本上是所有内存访问优化.主要的解释器和引擎都将分析与功能,变量和属性访问相关的代码中的问题,例如访问图的形状的频率和形状; 然后,利用所有这些信息,优化其隐藏结构,以便更有效地进行访问.到目前为止,对代码进行循环替换或进程分析基本上没有优化,因为它在大多数情况下运行时进行了优化(如果代码的特定部分确实需要花费过长的时间,它可能会对代码进行优化) .

首次执行JavaScript代码时,V8利用full-codegen直接将解析后的JavaScript转换为机器代码而无需任何转换.这使它可以非常快速地开始执行机器代码.请注意,V8不使用中间字节码表示,因此无需解释器.

当代码运行一段时间后,探查器线程已经收集了足够的数据来告诉应该优化哪个方法.

接下来,Crankshaft优化开始于另一个线程.它将JavaScript抽象语法树转换为名为Hydrogen的高级静态单指派(SSA)表示,并尝试优化氢图.大多数优化都是在这个级别完成的.
- https://blog.sessionstack.com/how-javascript-works-inside-the-v8-engine-5-tips-on-how-to-write-optimized-code-ac089e62b12e

*虽然continue可能导致执行转到下一次迭代,但它仍然算作循环的迭代.

  • 你的渐近分析是不正确的.过滤不能增加数组的大小,因此m <= n且O(n + m)= O(n +(x)n)= O((1 + x)n)= O(n)其中0> = x> = 1. (4认同)