Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何解释js数组循环中无法执行的性能?_Javascript_Arrays_Performance - Fatal编程技术网

Javascript 如何解释js数组循环中无法执行的性能?

Javascript 如何解释js数组循环中无法执行的性能?,javascript,arrays,performance,Javascript,Arrays,Performance,假设我们有一个200000个元素的数组,例如。。。 现在我们想用不同的方法迭代它,并检查最快的方法。我听说,如果我们在循环之前将array.length保存在variable中,我们将减少执行时间,所以我尝试了下面的代码 let sum = 0 for (let i = 0; i < arr.length; ++i) sum += arr[i] let sum=0 对于(设i=0;i

假设我们有一个200000个元素的数组,例如。。。 现在我们想用不同的方法迭代它,并检查最快的方法。我听说,如果我们在循环之前将array.length保存在variable中,我们将减少执行时间,所以我尝试了下面的代码

let sum = 0
for (let i = 0; i < arr.length; ++i) sum += arr[i]
let sum=0
对于(设i=0;i
反对

let sum = 0
for (let i = 0, l = arr.length; i < l; ++i) sum += arr[i]
let sum = 0
for (let i = 0, l = arr.length; i < l; ++i) {
  sum += arr[i]
  if (i === 100) arr.pop()
}
let sum=0
对于(设i=0,l=arr.length;i
但我得到了相同的结果,就好像在这两种情况下,js一开始只读取一次长度值

然后我决定检查,若在循环过程中我们将更改一个数组,删除最后一个元素,会怎么样

let sum = 0
for (let i = 0; i < arr.length; ++i) {
  sum += arr[i]
  if (i === 100) arr.pop()
}
let sum=0
对于(设i=0;i
反对

let sum = 0
for (let i = 0, l = arr.length; i < l; ++i) sum += arr[i]
let sum = 0
for (let i = 0, l = arr.length; i < l; ++i) {
  sum += arr[i]
  if (i === 100) arr.pop()
}
let sum=0
for(设i=0,l=arr.length;i
所以我认为第二种情况应该更快一些,因为在第一种情况下,js不可避免地每次都要检查array.length,我很惊讶它不是更快,而是更慢——从10%到15%。对我来说这是无法解释的。有什么想法吗

测试:

问题是

let sum = 0
for (let i = 0, l = arr.length; i < l; ++i) {
  sum += arr[i]
  if (i === 100) arr.pop()
}
let sum=0
for(设i=0,l=arr.length;i
现在不正确,因为它循环超出了数组的末尾。最后,
sum
将是
NaN
。正确的解决方案应该是
l=arr.length-1
,这样就不会发生这种情况

现在为什么它变得如此缓慢?因为javascript中的数组访问只有在元素存在时才是快速的(编译成带指针寻址的快速路径)。当您错过时,代码将被去优化。由于JSbench多次运行相同的代码,因此即使去优化只发生在200000次迭代的最后一次,后续的运行也会慢得多


有关详细信息,请参阅,其中甚至明确说明了“避免越界读取”。一般来说
i
是惯用的,JS引擎会很好地对其进行优化。

您需要在多个浏览器供应商上进行测试,因为很多时候性能差异归结为底层浏览器实现,例如,我在Safari上运行了你的测试
13.1.1
,他们的分数都差不多,只有最后一个稍微落后于
934次操作
vs
938次操作
two@RickySpanish,对不起,我不小心改变了我的测试,一second@RickySpanish,请现在查看,我在topici中只提到了两个案例,我检查了您的新测试台v2,在Safari上,第二个测试案例在
944 op/s
时快11%,而第一个
837 op/s
。不过,这让我很好奇,所以我尝试了
chromium 86
,它运行两个测试的速度都快了很多,但更有趣的是,第一个测试用例在
4010 op/s
时快了10%,而第二个测试用例的成绩是
3633 op/s
,现在我也尝试了Firefox,它同样像Safari(尽管快了很多)第二次测试以
4174 op/s
8%的速度获胜。。。chromium做了一些事情,使第一个测试用例更快,尽管我不知道具体是什么gives@interesting,我只有opera和chrome,都显示相同的内容results@Bergi,这个错误是正确的,但我将它改为
if(i==1000){arr.pop(),l--}
应该解决问题,但性能是关键same@DmitryReutov对我来说,性能确实有了很大的提高,从1100次/秒提高到1250次/秒。但是,使用
i
的原始代码在1400次运行/秒时仍然更快。不知道为什么会这样。这很奇怪……无论如何,谢谢你的新消息,我会读的it@DmitryReutov你用的是什么浏览器?我链接的资源是关于V8(最流行的引擎,在Google Chrome和Node.js中使用)的内部内容,但是一般的建议对所有引擎都是一样的。我可以检查几个引擎的输出,但是是的,Chrome是优先的