2017-07-30 76 views
1

假设我们需要检查1百万用户,应该怎么做?Javascript循环性能

for (var i = 0;i<1000000;i++){ 
    users[i].abc(); 
    users[i].abc2(); 
} 

for (var i = 0;i<1000000;i++){ 
    var user = users[i]; 
    user.abc(); 
    user.abc2(); 
} 

哪一个会更快,为什么?

+4

的差别是微不足道的。 – Pointy

+0

由于较少使用属性访问器,带有'temp'的版本变得更快。 –

+0

这取决于js引擎,具体取决于引擎和“用户”的类型,可能根本没有差别,因为它可能导致相同的机器代码。 –

回答

1

第二个循环快了大约20%-30%。查看下面的代码片段的结果。即创建参考所需的时间比通过数组中的索引寻址需要的时间更少。

var users = []; 
 

 
for (var i = 0;i<1000000;i++){ 
 
    users.push({abc: function() {}, abc2: function() {}}); 
 
} 
 

 
var now = new Date(); 
 

 
for (var i = 0;i<1000000;i++){ 
 
    users[i].abc(); 
 
    users[i].abc2(); 
 
} 
 

 
console.log('The first loop requires ' + (new Date().getTime() - now.getTime()) + 'ms'); 
 
now = new Date(); 
 

 
for (var i = 0;i<1000000;i++){ 
 
    var user = users[i]; 
 
    user.abc(); 
 
    user.abc2(); 
 
} 
 

 
console.log('The second loop requires ' + (new Date().getTime() - now.getTime()) + 'ms');

+0

这是不正确的,第二个循环更快的原因是,因为引擎已经“热身”在第二个循环。交换循环,首先设置底部,然后你仍然可以得到相同的结果,它与变量无关,只是差别非常小,引擎被预热会产生很大的差异。 – adeneo

+0

下面是一个比较精确的例子 - > https://jsfiddle.net/adeneo/9pt8pkgc/,最好是使用https://jsperf.com/for-loop-333来做这种事情。 – adeneo

0

循环版本1将运行速度较慢,但​​会占用较少的内存。原因是它每次循环迭代2次访问迭代器i

循环版本2将运行得更快,但会消耗更多的内存。原因是它每循环迭代只访问一次数组,但会创建一个变量实例(user)。

话虽如此,两个版本都非常相似,所有的性能/内存使用差异是基本上不重要

+0

内存使用率可以忽略不计。 –

+0

@NinaScholz在这个问题上的一切都可以忽略不计,但我猜测OP有一个问题的原因... –

0

根据https://en.wikipedia.org/wiki/Chrome_V8,v8编译器会将您的代码编译为本机机器码。

根据编译器进行的优化,您没有确切的方式来确保哪个版本更快。

正如在其他答案中指出的那样,如果有差异的话,这个差别就没有关系了。

的编译的代码被附加地优化(和重新优化)基于代码的执行 轮廓的启发式 在运行时动态。使用的优化技术包括内联,昂贵的运行时属性的省略,以及内联缓存等等。

因此,考虑到您的情况的要点不是基于执行速度。

我会说,如果你跑了很多的users[i]然后取消引到本地user变量是确定的,因为它可以节省您的字符输入("s[i]"

如果你只运行一个或两个从长远来看, users[i]然后继续,因为解引用将只使用更多的行代码。

总之,我会选择更紧凑的代码。


UPDATE:

我试图@Alexander Elgin代码,并显示从50%到20%的速度增加在本地执行的巨大差异,所以它不是“无关紧要”,因为我和别人说( +1)

但是,我坚持认为这一切都取决于执行引擎所执行的优化,但实际上在我的nodejs版本中,取消引用似乎在巨大的循环上要快得多。