[英]Why is implicit casting is much faster than explicit in JS? Is implicit casting a good practice?
我知道像String(1234)
和Number("1234")
這樣的類型是更干凈和更好,但我只是嘗試對同樣的事情進行基准測試,特別是"" + 1234 // -> "1234"
和- - "1234" // -> 1234
。
結果非常令人驚訝(對我而言)。 我在Chrome中每次迭代100,000次。
我使用了這個簡單的代碼。
var then = Date.now();
for (var i = 0; i < 100000000; ++i) {
var a = - - "1234";
};
console.log(Date.now() - then);
Number("1234")
花費了2351毫秒而- - "1234"
只花了748毫秒。
類似地,換句話說, String(1234)
花了3701 ms,而"" + 1234
只花了893 ms。
差異非常大。
我的問題是:是什么使得顯式轉換比隱式更慢? 我的直覺告訴我它應該是另一種方式。
使用隱式強制轉換是一種好習慣嗎? 特別是hacky - - "1234"
? 還有更好的選擇嗎?
PS:我在Firefox中嘗試過同樣的方法。 它大約慢了500倍(但隱式轉換仍然快得多)。 到底是怎么回事? 它是否與分支預測或類似的東西相關聯? 我想我的基准測試錯了。
如果您不使用常量,如果您使用i
instant,那么結果將完全不同:
console.time('a');
for (var i = 0; i < 1e7; ++i) {
var a = String(i);
};
console.timeEnd('a');
console.time('b');
for (var i = 0; i < 1e7; ++i) {
var a = "" + i;
};
console.timeEnd('b');
輸出:
a: 1062.192ms
b: 884.535ms
注意我也必須刪除10的冪。 100000000 === 1e8
我使用1e7
。
這表明,在基准測試中使用常量時會發生很多優化。
而現在Number(...)
似乎更快:
console.time('a');
for (var i = 0; i < 1e7; ++i) {
var a = - - ("" + i);
};
console.timeEnd('a');
console.time('b');
for (var i = 0; i < 1e7; ++i) {
var a = Number("" + i);
};
console.timeEnd('b');
輸出:
a: 2010.903ms
b: 1557.735ms
理論上,使用一元+
和-
運算符應該比調用Number和String更快,因為它們使用內部ToNumber和ToString方法將操作數轉換為數字Type,而Number和String需要函數調用的額外開銷。
但是,理論並不總是與實踐相匹配,因為將Number(x)
優化為+x
可能非常簡單,反之亦然,編譯器認為這種算法更快。
是什么讓顯式轉換比隱式更慢? 我的直覺告訴我它應該是另一種方式。
與往常一樣,您在特定版本的瀏覽器中獲得的結果不一定適用於其他瀏覽器甚至同一瀏覽器的其他版本。 理論上,顯式轉換應該更慢,但我不會依賴於實現。
使用隱式強制轉換是一種好習慣嗎? 特別是hacky - - “1234”? 還有更好的選擇嗎?
這應該是-'1234'
,我會說“不”,因為-
運算符將它的參數轉換為數字無論如何,從來沒有必要寫x - -y
。
與加法運算符+
一起使用一元+
進行轉換更常見,在大多數情況下,寫+x
或Number(x)
也同樣清楚。 所以使用:
x + +y
並節省一些打字。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.