2017-07-30 106 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版本中,取消引用似乎在巨大的循環上要快得多。