2013-08-02 101 views
2

我正在爲實用工具專門開發一個庫。它將有幫助你操作的函數:字符串,數組,數字,對象等等。性能是主要關注點。雖然對字符串重複功能工作(重複字符串n次數),我決定測試一下有多快我目前的方法:爲什麼負循環如此之快?

Array(n + 1).join(string); // n = times to repeat; string = string to copy 

相比於只使用一個循環。事實證明,雖然這是重複字符串的最短路線,但它也是最慢的。我知道它仍然很快。我的意思是,一個人不可能在1秒內完成20萬件事情,但是與循環相比它很慢。

什麼使循環如此之快?一個循環我注意到,特別是快的,同時循環含有i--

var i = 10; 
while (i--) { 
    // do stuff 
} 

我決定,因爲它是最快的使用這種方法。但我想知道爲什麼?是什麼讓它比其他方法快得多?

這裏是my benchmark。 Opera中只有while循環比for循環慢的唯一瀏覽器。這是特別快的Internet Explorer 10

+0

問爲什麼一個「負循環」的速度真快,只有與「正循環」或for循環相比才有意義。你在這裏問的是「爲什麼一個循環比創建一個數組並使用我的字符串加入未定義的元素更快?」我知道你在性能測試中有其他循環的情況,但是請注意,你的負循環不是等價的,它應該是'for(var i = 10; i - ;)' – nnnnnn

+1

你的minusWhile非常快,因爲它永遠不會在循環體中做任何工作,並且都不做......雖然......除此之外,你應該注意到循環基本上是相同的速度。一般來說,沒有免費的午餐:只要你看到這樣的異常值,就調試你的測試代碼。如果你的重複次數超過10次,我會期望Array.join方法超越性能循環。 – dandavis

+0

@nnnnnn:你確定「var i = 0; while(i--){」做了什麼? (我不這麼認爲......)另外,如何將工作翻一番或者甚至三倍,導致性能降低數十倍,而不是降低2-3倍? – dandavis

回答

0

你的JS PERF有很多缺點,你必須:

  • 關閉一,關十,並關閉九個錯誤
  • 代碼測試內聯
  • 沒有檢查結果

fixed jsperf結果讓 更有意義:

enter image description here

請注意,+= str進行了優化,更像是使用StringBuilder。如果那是你的困惑。 Array代碼分配一個新數組並調用join,這是一個具有複雜語義的複雜函數。 V8還沒有優化.join

對於其他代碼,它們在每次運行時總是非常接近,因此它們具有相同的性能。


重複的包含錯誤信息也一樣,如果你是通過一個數組,那麼你的工作對CPU緩存循環,這樣不但爲負幾乎在最好的情況下相同,但也差,如果你是循環通過一個數組。它也出現在jsperf

相關問題