2011-09-07 12 views
9

兩天前,當我發現jsperf.com其中有很多javascript性能測試的集合時,我瀏覽了幾個測試。爲什麼在計算哪個數字更大時,Firefox和其他瀏覽器會執行相反的操作?

其中一項測試是this,它比較了Math.min(a,b)a<b?a:b。當我在Google Chrome上運行此測試時,結果發現a<b?a:bMath.min(a,b)快得多(在Chrome 14上,第一個是53,661,381 ops/s,第二個是419,830,711 ops/s)。其他網頁瀏覽器也有類似的結果。

但是,在Firefox上,結果是相反的。 Math.min(a,b)a<b?a:b快得多!第一個是374,219,869 ops/s和第二個是79,490,749 ops/s在Firefox 6

enter image description here

當我張貼這在Facebook上,有人說,「由於Firefox是開源項目,開發人員優化Math.min,但谷歌瀏覽器沒有,因爲Google Chrome只是對Chromium的修改「,但是(除了上述說法並不完全正確),因爲這並不能解釋Google Chrome的a<b?a:b和Firefox的Math.min(a,b)以相似的速度執行的原因,Google Chrome的Math.min(a,b)和Firefox的a<b?a:b以相同的速度執行,因爲如果Firefox比Google Chrome更快,那麼Googl Chrome的Math.min(a,b)應該比Firefox的a<b?a:b慢得多。

摘要:

  1. 在其他瀏覽器,a<b?a:bMath.min(a,b)更快。
  2. 但是,在Firefox上,Math.min(a,b)a<b?a:b快。
  3. 由於Math.min(a,b)在Firefox的速度≒的a<b?a:b谷歌瀏覽器的速度和a<b?a:b速度在Firefox≒的Math.min(a,b)速度上的谷歌瀏覽器「Firefox是慢」或「火狐快」不能成爲理由。

這是怎麼發生的?

+4

原因?除此之外,每個指定的瀏覽器都有自己的JavaScript實現,因此可以自由優化,不過他們喜歡。 – Jamiec

+0

@Jamiec但是我認爲'a JiminP

+0

@Jiminip對'Math.min'的調用將被編譯,並且該方法可能會被內聯。也許在Firefox中,它是用超快代碼來內聯的,而'if'仍然是'if'。 – xanatos

回答

8

這裏有幾件事情正在進行。

首先,在Firefox 6中有兩種不同的JIT編譯器:TraceMonkey和JaegerMonkey。哪一個被用於給定的代碼位取決於一些啓發式;這些啓發式方法傾向於使用TraceMonkey來處理函數調用的代碼。恰巧,對於足夠簡單的代碼,TraceMonkey幾乎總是比JaegerMonkey快;特別是在這裏介紹的代碼片段就是這種情況。

在這個特定的基準測試中,Math.min代碼路徑使用Tracemonkey進行編譯,因爲它是一個函數調用。三進制運算符代碼路徑使用JaegerMonkey進行編譯。

您可以通過轉到about:config,將jit放入過濾器字段並禁用TraceMonkey(列表中的tracejit)和JaegerMonkey(methodjit)中的一個或兩者來試驗。如果你這樣做,你會發現在這個特定的基準測試中,三元運算符對於每個編譯器都是單獨運行的,因此與其他瀏覽器相比你看到的反轉只是使用不同編譯器的一個函數。

現在至於爲什麼Math.min通常比三元操作符慢...首先它需要做更多的工作;如果您仔細測試,它返回的答案與三元運算符不同。其次,它通常是作爲函數調用來實現的,這是大部分開銷來自的地方(儘管TraceMonkey實際上在生成的代碼中顯式地內聯它,這就是爲什麼TraceMonkey中兩個片段的性能不同)。

1

我讀過這個問題後,在Dev.Opera上讀取了Efficient Javascript,並運行了一些不同的基準。我認爲這部分有點誤導。有很多事情會減慢Math.min的速度,但沒有一個能夠真正解釋Google Chrome與Firefox或IE9的性能。

事情我想慢下來Math.min

  • 利用arguments對象
  • 必須檢查是否有值爲NaN
  • 其他事情一樣,如果無參數給出並返回無限+ 0> -0

有關更多深入信息,請參閱http://qfox.nl/ecma/366以獲取示例實現。

P.S.我知道這個問題很老,但我認爲如果我去過去,這可以節省一些時間。

相關問題