node.js での次のコードのパフォーマンスの奇妙な動作に気付きました。のサイズcontent
が 1.4KB の場合、リクエストの応答時間は約 16ms です。ただし、 のサイズcontent
がわずか 988 バイトの場合、リクエストの応答時間は奇妙に長くなり、約200 ミリ秒になります。
response.writeHead(200, {"Content-Type": "application/json"});
response.write(JSON.stringify(content, null, 0));
response.end();
これは直感的ではないようです。Firebug の net タブを見ると、増加/差異はすべて受信によるものです (一方、待機は両方とも 16ms です)。
どちらの場合も応答時間が 16ms になるように、次の変更を加えて修正しました。
response.writeHead(200, {"Content-Type": "application/json"});
response.end(JSON.stringify(content, null, 0));
node.js docを調べましたが、これまでのところ関連情報が見つかりませんでした。これはバッファリングに関連していると思いますが、node.js は と の間write()
でプリエンプトできend()
ますか?
アップデート:
これは、Linux の v0.10.1 でテストされました。
ソースを覗いてみたところ、2 つのパスの違いを特定できました。最初のバージョンには 2 つの Socket.write 呼び出しがあります。
writeHead(...)
write(chunk)
chunk = Buffer.byteLength(chunk).toString(16) + CRLF + chunk + CRLF;
ret = this._send(chunk);
this._writeRaw(chunk);
this.connection.write(chunk);
end()
ret = this._send('0\r\n' + this._trailer + '\r\n'); // Last chunk.
this._writeRaw(chunk);
this.connection.write(chunk);
2 番目の適切なバージョンには、Socket.write 呼び出しが 1 つだけあります。
writeHead(...)
end(chunk)
var l = Buffer.byteLength(chunk).toString(16);
ret = this.connection.write(this._header + l + CRLF +
chunk + '\r\n0\r\n' +
this._trailer + '\r\n', encoding);
最初のバージョンが小さい応答サイズでうまく機能しない理由はまだわかりません。