2013-06-21 24 views
2

我正在編寫一個處理來自多個連接的傳入數據的Node.js中的TCP服務器。 服務器解析傳入的數據流並返回存儲在數據庫中的對象。 我試圖做一些性能優化,並測試了兩種編碼方法:節點js事件偵聽器。使用匿名回調函數或聲明的函數來獲得性能?

  • 代碼段1使用嵌套的匿名回調。
  • 代碼段2使用聲明 函數來替換匿名回調函數。

我認爲snippet 2會更快,因爲它避免了爲每個新的傳入數據包創建新的函數對象。 但是,在現實生活中,代碼片段1似乎快了20%。

有誰知道爲什麼?

片段1:

function TcpOnConnection (stream) { 
    stream.on("data", function(data) {  
     parseTcp(data,function(err,obj) {    
     if (err) console.log(err.message); 
     if (obj) { 
      stream.write(obj.returnMsg); 
      storeData(obj); 
     } 
     }); 
    }); 
} 
TCPserver.on("connection",TcpOnConnection); 

片段2:

function TcpOnConnection (stream) { 
    function handleParsed(err,obj) {    
     if (err) console.log(err.message); 
     if (obj) { 
     stream.write(obj.returnMsg);  
     storeData(obj); 
     }     
    } 

    function StreamOnData(data) { 
     parseTcp(data,handleParsed);    
    } 

    stream.on("data", StreamOnData); 
} 
TCPserver.on("connection",TcpOnConnection); 

回答

1

函數聲明不避創建一個新的函數對象或關閉,只是因爲它是一個函數的聲明 - 他們擁有相同的機制在這方面。事實上,你不僅僅是創建一個函數對象,而是一個常規對象(每個函數都帶有一個新的對象,你可以參考.prototype,儘管至少在V8中它似乎只在需要時才創建)。

函數是第一類對象,它的缺點是必須爲每個函數創建一個單獨的對象,而不管它是什麼。

確保您所有的功能無論是在模塊範圍或 功能,只有每個應用程序執行一次內部或者創建:

function handleParsed(err, obj) { 
    if (err) console.log(err.message); 
    if (obj) { 
    //What I'm doing here is only possible if 
    //`this` refers to the stream 
    //That depends how parseTcp calls the callback 
    this.write(obj.returnMsg); 
    storeData(obj); 
    } 
} 

function StreamOnData(data) { 
    parseTcp(data, handleParsed);  
} 

function TcpOnConnection (stream) { 
    stream.on("data", StreamOnData); 
} 
TCPserver.on("connection",TcpOnConnection); 
+0

我有點困惑。當「stream」僅存在於「TcpOnConnection」範圍內時,「this」如何引用「stream」? parseTcp函數不知道流對象。在成功解析結束時,parseTcp只是簡單地調用「handleParsed」回調。 –

+0

@SeppVanRompaey對,雖然'StreamOnData'應該設置爲'stream',所以也許你可以從那裏傳遞它呢? – Esailija

+0

@SeppVanRompaey'this'取決於函數的調用方式,而不是範圍。流應該調用數據回調,比如'.call(this,data)',然後'this'將引用回調中的'stream'。就像jQuery或DOM事件偵聽器通過'.calling'工作,'this'設置爲事件的元素目標。 – Esailija