2013-07-16 53 views
-88

有沒有在條件運算符===和賦值運算符=之間的性能有什麼區別?我寫了一些預存鉤中間件貓鼬,我想知道如果有太多的速度差的:JavaScript性能,條件語句VS賦值運算符

UserSchema.pre('save', function (next) { 
    if (!this.isModified()) { 
     return next(); 
    } 
    this.crm.isUpToDate = false; 
    next(); 
}); 

UserSchema.pre('save', function (next) { 
    if (!this.isModified()) { 
     return next(); 
    } 
    if (this.crm.update === true) { 
     this.crm.isUpToDate = false; 
    } 
    next(); 
}); 

編輯:

感謝您的建設性註釋。

基本上,它看起來沒有太大的差異(如上所述,它可以忽略不計)。感謝這個測試速度很快的工具http://jsperf.com/,我從來沒有聽說過它。

對於那些想知道代碼的人來說,首先我在原始文章中做了一個明顯的錯誤,然後當每個人都試圖向我指出我哭的時候,這可能是大家低估的原因。

下面是我在做什麼:

我必須先預存貓鼬中間件掛鉤(對於蒙戈數據庫),其中鉤子獲取運行的每一個文件保存時間。在保存時我檢查文檔是否已更新。如果是這樣,我將crmIsUpToDate設置爲false。當cron作業獲取時,crmIsUpToDate將被設置爲true。這個鉤子可以在cron作業到達文檔之前運行多次。

我不認爲這是問題所有必要的,因爲問題是如果做比較===和做任務=之間是有區別的。我甚至不應該把代碼放在上面,因爲它真的減損了主要問題。

+12

1)任何性能增益都可以忽略不計; 2)http://jsperf.com –

+14

這兩個例子不會做你知道的同樣的事情? – adeneo

+3

即使有,是否有關?它們不執行相同的功能,因此不能可靠地進行基準測試。 – War10ck

回答

37

當您有一個非引用語言(不是JavaScript)並且執行一個大對象的賦值('=',導致複製操作)時,它可能會「慢」。因此,檢查複製操作是否真的必要可以爲您節省大量時間。

但是JavaScript是一種天然的引用計數的語言:

object1 = {a: 1, b: 2}; 
object2 = object1;   // refcounting copy? 
object1.a = 3;    // test by modifying the first object 
console.log(object2.a); // will return 3 => refcounting 

=>因此所有賦值操作( '=')是相當便宜。

而且,甚至更多的是,您正在使用原生數據類型(布爾,數字將是相同的),可能更快或至少與對象一樣快。
注意:字符串不會在JavaScript中被引用,在這種情況下它們是一個例外。

所以,現在我們已經瞭解到這項任務很便宜。但身份檢查('===')呢?

在您的代碼中,您必須通過對象thiscrmupdate - 這需要一些額外的時間。然後必須檢查類型(bool)的相同性,然後如果內容(false)相同。
所有這些都是在程序流程中添加條件的地方,現代CPU與他們的長管道可能會猜測分支錯誤地創建了一個停頓並重新加載了整個管道。這也浪費了很多CPU週期(儘管現代CPU現在相當不錯)。

=>此比較('===')相當昂貴。

結論1:
您不應該以昂貴的測試,可以很容易地避免保護便宜的代碼。
當代碼變得越來越昂貴的時候,測試會在最後節省時間。這導致:

結論#2:
不成熟的優化是邪惡的!它可以使代碼難以閱讀,引入新的錯誤,使代碼更大(對緩存效率也不好),...
=>只優化那些您確定在性能問題中運行的代碼部分 - 並且那麼僅基於分析信息。人類在猜測這裏的效果時很不好...