13

我已經看到了一些性能關鍵的JavaScript代碼,就像this project的一個廣泛使用位或運算的以0例:什麼是一些javascript程序員現在使用的asm風格「x | 0」?

GameBoyAdvanceCPU.prototype.write8 = function (address, data) { 
address = address | 0; 
data = data | 0; 
this.memory.memoryWrite8(address | 0, data | 0); 

我知道的情況下使用數字地板用「| 0 「,但這不是這種情況,因爲這些總是int。它看起來有點像asm.js,這是否告訴js引擎我們正在使用整數,允許進行一些優化?如果是這樣,哪些瀏覽器將進行這些優化?

任何指向這種工作方式的指針都會令人滿意。

+0

@RobG它不等同於'4.2'值。 – zerkms

+2

這是asm.js風格。它將值強制爲32位整數,這比浮點快。 –

+0

@RobG:而不是'3141592658'。 – Bergi

回答

-1

|運營商是bitwise OR。它用於對兩個整數進行逐位或運算。

這裏的用法是一個非常類似於邏輯或的快捷方式。運營商提供的默認值,不同之處在於結果是整數只(而不是字符串...等)

address = address | 0; 

的意思是「如果地址是一個數字,讓我們使用它,否則,將其設置爲0" 。

+0

這樣做的意義何在?爲什麼要選擇'||'(如果真的話會真的短路)? – zerkms

+0

@zerkms,我不確定。我只能猜測,也許他們想確保它是一個數字,所以它不會破壞代碼。如果地址是「foo」,則||將不會生效... – BernieDADA

1

什麼它實際上可以在此fiddle

看到它的探測對整型變量在這種情況下,要麼「地板」,或者如果不是整數設置爲0。

因此,與a = a || 0存在巨大差異,這將不會改變3.2的值。

+0

嘗試用'3141592658'。 – Bergi

+0

@Bergi嗯,有趣。需要更多的調查... –

3

引用the Ecmascript 5 spec: 11.10 Binary Bitwise Operators,即

生產A : A @ B,其中@是 位運算符中的一個以上的製作(&; ^; |),如下評價:

lref是評估結果A.
lvalGetValue(lref)
rref成爲評估B的結果。
rvalGetValue(rref)
lnumToInt32(lval)
rnumToInt32(rval)
將應用位運算符@的結果返回給lnumrnum。結果是一個有符號的32位整數。

,並指出,ToInt32() is defined as

number是對輸入參數調用ToNumber的結果。
如果號碼是NaN+0−0+∞−∞,則返回+0
posIntsign(number) * floor(abs(number))
int32bitposInt2^32;也就是Number類型的有限整數值k,其類型爲正符號且小於2^32,使得posIntk的數學差異在數學上爲2^32的整數倍。
如果int32bit大於或等於2^31,則返回int32bit − 2^32,否則返回int32bit

然後,它在邏輯如下(你可以在自己的控制檯確認)與例如

((Math.pow(2, 32)) + 2) | 0 === 2 
(Math.pow(2, 31)) | 0 === -2147483648 === -(Math.pow(2, 31)) 

等等。

簡而言之,操作將數字轉換爲32位整數(具有它的訣竅,參見上面的第二個示例和ToInt32()定義以獲得解釋),然後執行邏輯或具有零不變的操作輸出超出第一次轉換。

從本質上講,將數字轉換爲32位整數非常節省成本,因爲1)它依賴於瀏覽器內置的ToInt32();和2)ToInt32(0)0短路(見上述規範),因此實際上不增加額外的開銷。

+1

+1,非常好。儘管如此,我仍然對這個優化角度感興趣:爲什麼要將瀏覽器調用到Int32,是否js引擎會更快地執行某些操作? –

+1

@DiogoFranco當我評論另一個答案時,我已經看到人們_claim_它提供了很多次性能提升,但我還沒有看到任何人演示代碼,實際上它確實會帶來更好的性能,除了將它用作轉換以確保參數是給定類型。像[我剛剛創建的這個Jsperf]測試(http://jsperf.com/bitwise-or-0-performance)沒有顯示任何可識別的速度差異(我嘗試了許多不同的算術和邏輯運算,使用不同的參數,隨時嘗試自己)。 – Nit

+0

簡單的jsperf長凳的好處不會顯示這種事情的結果。它涉及向瀏覽器提供靜態類型提示,並在瀏覽器在長期運行時對這些東西進行JIT操作時緩解緊急情況。 –

5

根據() | 0JavaScript Performance for Madmen

包裝整數算術表達式允許運行,以確保你正在做的整數運算代替浮點運算。這樣可以避免檢查溢出並在很多情況下生成更快的代碼。

根據頁面,「最」Javascript運行時確實如此,但沒有說哪個。

作爲第二個來源,Writing Fast JavaScript For Games & Interactive Applications狀態

告訴JavaScript引擎,我們希望存儲整數值[...]我們可以使用按位或操作員:

,並從第三源Microsoft's Writing efficient JavaScript page

明確地告訴JavaScript運行時使用整數算術使用按位或運算符

此外,除了評論,上面沒有提到asm.js,所以我懷疑這種優化適用於沒有明確標識爲asm /的瀏覽器中沒有明確識別它的代碼。

+0

我已經多次提出索賠,但是我還沒有看到任何人在除快速轉換之外的任何地方實際展示直接速度收益。 – Nit

相關問題