2

我正在用 Node.js 编写一个 TCP 服务器来处理来自多个连接的传入数据。服务器解析传入的数据流并返回存储在数据库中的对象。我正在尝试对性能进行一些优化,并测试了两种编码实践:

  • 片段 1 使用嵌套的匿名回调。
  • Snippet 2 使用声明的函数来替换匿名回调。

我假设片段 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);
4

1 回答 1

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);
于 2013-06-21T09:37:31.837 回答