16

幾周前,我已閱讀此主題Is < faster than <=?關於比較運算符C。據說在<<=之間的性能沒有差別,因爲它們被解釋爲相同/相似的機器命令。JavaScript - === vs ==運營商性能

與此同時,在我們公司的「最佳實踐」,有人說,我們應始終使用「===」比較的東西,而不是「==」。於是,我開始懷疑,因爲我習慣使用「==」和「的typeof ... ==」,不想改變我的寫作方式這始終是合適的: - ]

注意這是在JavaScript的上下文中。

所以,我有一個小小的研究,這裏Which equals operator (== vs ===) should be used in JavaScript comparisons?據說:

這是因爲平等的==操作符不會強制類型轉換...這意味着 的解釋隱含試圖將這些值轉換然後 做比較。

在另一方面,身份操作===不做型 強制,所以這樣就不會轉換值 的值進行比較

的時候,我開始懷疑,如果這意味着當我使用「===」運算符時,我將獲得良好的性能,因爲沒有資源用於轉換操作數。所有代碼轉換爲機器命令後,這是否意味着當您使用<<=時,在C中沒有區別,這與JavaScript和其他語言中的相同?

+18

地獄的路徑鋪設微優化。 – asawyer

+4

「而且畢竟編碼變成了機器命令」但是並不是每個不同語言的相同指令都必須變成相同的機器碼。 – BoltClock

+2

嘗試採取一個看起來這個帖子:http://stackoverflow.com/questions/8044750/javascript-performance-difference-between-double-equals-and-triple-equals – Chase

回答

0

對於js,===運算符將返回true,如果用於字符串類型和字符串完全相同的字符。對於對象,它比較對象引用,而不是內容。

ECMA standard

11.9.6全等比較算法的比較X === y,其中x和y是數值,產生真或假。

  1. 如果Type(x)是從式(y)的不同,返回false:這樣的比較 如下進行。
  2. 如果Type(x)是Undefined,則返回true。
  3. 如果Type(x)爲Null,則返回true。
  4. 如果Type(x)是Number,那麼 a。如果x是NaN,則返回false。 b。如果y是NaN,則返回false。 c。如果x與y的Number值相同,則返回true。 d。如果x是+0且y是-0,則返回true。 e。如果x是-0並且y是+0,則返回true。 f。返回false。
  5. 如果Type(x)是String,則返回true,如果x和y是完全相同的字符序列(在 對應位置中具有相同的長度和相同的字符);否則,返回false。
  6. 如果Type(x)是布爾型,則返回true,如果x和y都爲真或兩者都爲假;
+6

這包含一些錯誤的信息(並且小編輯太多了)。沒有要求'str === str'只適用於同一個對象。 ''a「+」b「===」ab「'是真實的,但並不要求''a」+「b」'與同一個對象被作爲「ab」'。雖然*'=='和'==='可以「儘早停止」,如果*實現*決定都是相同的對象值(這將是一個特定於實現的優化,可以在* some *個案中使用) ,否則必須將字符串值與'==='逐個字符進行比較。 – 2012-09-11 17:39:01

+0

因此,畢竟,這個示例等號後面有很多邏輯: - ] ...感謝您的答案和ESMA書籍鏈接 - 我覺得這非常有趣。 – gotqn

+2

第一段幾乎完全不正確。如果您有興趣,我可以提供詳細的解釋。 (你是否在腦子裏寫了一種不同的語言?) –

3

無論您獲得的性能如何,===在這種情況下顯然是更好的選擇。任何其他如更好的表現只是蛋糕上的錦上添花。此外,兩種方式的差異都很小。

3

性能差異可以忽略不計,這意味着您不應該浪費寶貴的大腦週期來思考它。如果你真的想知道,你應該測試。

使用===,除非你有一個很好的理由不(你可能沒有)。

4

這是一種腳本語言。這些運營商的性能應該不是這麼重要,您應該擔心它,因爲還有其他一些功耗更高的功能,比如它在虛擬機中運行,輸入較弱,與在瀏覽器中一個HTML DOM ...

此外,無論是運營商做完全不同的事情,所以一個可能不互換與其他任何情況。

這麼說,我認爲(但沒有測試),其===更快。原因是,它只需要比較類型,如果匹配,則比較原始數據。 ==運算符將嘗試將一種類型轉換爲另一種類型,如果它們不匹配。在大多數情況下,這將是一個更昂貴的操作。

這是幸​​運的,因爲在大多數情況下===是更好的選擇。:)

但無論如何,你可以很容易地測試它(確保你測試多種情況下,都具有相同類型和幾種不同類型),但如果你不知道如何測試它,我會停止完全擔心它。如果有的話,這種差異不會殺死你。

+1

雖然泛型,像大多數這些答案'=='與'==='「性能」,我懷疑'=='和'==='的實際速度是基於提供的值的影響。雖然'=='規則「看起來更長」或「需要更多操作」,但應該認爲'=='是'==='的「超級匹配」,因此始終可以嘗試'= =='規則,如果在== ==規則之前有匹配則停止。當然,這最終將取決於許多其他因素,而不僅僅是*實施*。 – 2012-09-11 17:52:48

+1

@pst,這是正確的,但如果速度非常重要以至於不得不使用這種雙重檢查,則可能需要考慮與Javascript不同的語言。另外,如果你對類型嚴格(變量既可以是整數也可以是未賦值,但絕不是字符串),可以安全地使用嚴格比較運算符。即使在你需要'=='的情況下,你也可以先執行一個類型轉換。我認爲這會讓你的代碼更具可讀性和'更安全',這對我來說比速度更重要。 – GolezTrol

8

首先,性能根本不是問題。對於任何實際的腳本,相比代碼中的其他瓶頸(通常DOM操作將成爲頭號目標),使用一個操作符相對於另一個操作符的任何性能增益都將無限小。

其次,在許多情況下,=====將執行完全相同的步驟。當兩個操作數的類型相同(例如,兩個字符串或兩個數字)時,ECMAScript規範對兩個操作符的步驟完全相同。因此,如果您在一個瀏覽器或其他環境中觀察到兩個運算符之間的相同類型操作數的性能差異,則不能保證或者甚至可能在另一個瀏覽器中看到類似的差異。

typeof的情況下,在你的問題中提到,兩個操作數都保證是同一類型(字符串)和兩個運營商將做完全一樣的事情,所以唯一的理由在支持某運營商另一種是風格

作爲一個整體的JS社區已經在這方面變得更加強硬:共識似乎是「絕不使用==!=!=,除非你需要類型強制」,這對我的口味太過於教條。

+1

很多時候,我從服務器獲得了大量數據。設想一千行,並且這一行中的每個值都應該與其他值進行比較。如果信息以字符串形式返回,並且我將它與「==」進行比較,因爲它畢竟是一個「數字」,這意味着1000次祕密操作。這就是爲什麼我認爲表演很重要。 – gotqn

+0

@Joro:我不確定我是否理解你的觀點。如果你的操作數是不同類型的,那麼'==='和'=='將會有不同的行爲,所以沒有選擇:你必須使用那種你想要的比較。 –

+0

我明白你的觀點。我想說,你必須爲任何情況做好準備。返回記錄可能採用字符串格式,但過了一段時間和服務器功能更新後,就會像數字一樣返回。所以,根據我的更好的解決方案將使用「==」,因爲我不會被返回數據格式所依賴。 – gotqn

4

我覺得有一個可以容易驗證的證據答案是最好的。

這些操作是如此之小,所以很難性能測試它們。

  • == 1648真
  • === 1629真
  • 控制測試1575真

如果你減去關閉控制測試,它看起來像有一個約30%的差異他們在瀏覽器上的速度。如果你多次這樣做,你可以得到不同的答案,但===通常以最快的速度出現,我認爲這只是證明差異微乎其微的證明。

我認爲這幾乎證明別人在說,該性能差異的時間去思考一種浪費,但同時也表明,實際上===更快。希望這個答案可以節省其他人的時間,那些只需要看到證據的人。

var testString = "42"; 
 
var testNumber = 42; 
 
var testObject = {}; 
 

 

 
var start = Date.now(); 
 
var result = null; 
 
for(var i = 0; i < 100000000; i++){ 
 
    result = testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject 
 
} 
 

 
console.log("==", Date.now() - start, result); 
 

 
var start = Date.now(); 
 
var result = null; 
 
for(var i = 0; i < 100000000; i++){ 
 
    result = testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject 
 
} 
 
console.log("===", Date.now() - start, result); 
 
var start = Date.now(); 
 
for(var i = 0; i < 100000000; i++){ 
 
    result = true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true 
 
} 
 
console.log("control test", Date.now() - start, result);