http: reduce multiple output arrays into one

Now we are using `output`, `outputEncodings` and `outputCallbacks`
to hold pending data. Reducing them into one array `outputData`
can slightly improve performance and reduce some redundant codes.

PR-URL: https://github.com/nodejs/node/pull/26004
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
This commit is contained in:
Weijia Wang 2019-02-08 13:53:57 +08:00 committed by Weijia Wang
parent 2e405e576b
commit 0b585457ee
3 changed files with 23 additions and 29 deletions

View File

@ -374,10 +374,8 @@ function socketCloseListener() {
// Too bad. That output wasn't getting written.
// This is pretty terrible that it doesn't raise an error.
// Fixed better in v0.10
if (req.output)
req.output.length = 0;
if (req.outputEncodings)
req.outputEncodings.length = 0;
if (req.outputData)
req.outputData.length = 0;
if (parser) {
parser.finish();

View File

@ -70,9 +70,7 @@ function OutgoingMessage() {
// Queue that holds all currently pending data, until the response will be
// assigned to the socket (until it will its turn in the HTTP pipeline).
this.output = [];
this.outputEncodings = [];
this.outputCallbacks = [];
this.outputData = [];
// `outputSize` is an approximate measure of how much data is queued on this
// response. `_onPendingData` will be invoked to update similar global
@ -220,14 +218,18 @@ OutgoingMessage.prototype._send = function _send(data, encoding, callback) {
data = this._header + data;
} else {
var header = this._header;
if (this.output.length === 0) {
this.output = [header];
this.outputEncodings = ['latin1'];
this.outputCallbacks = [null];
if (this.outputData.length === 0) {
this.outputData = [{
data: header,
encoding: 'latin1',
callback: null
}];
} else {
this.output.unshift(header);
this.outputEncodings.unshift('latin1');
this.outputCallbacks.unshift(null);
this.outputData.unshift({
data: header,
encoding: 'latin1',
callback: null
});
}
this.outputSize += header.length;
this._onPendingData(header.length);
@ -254,7 +256,7 @@ function _writeRaw(data, encoding, callback) {
if (conn && conn._httpMessage === this && conn.writable && !conn.destroyed) {
// There might be pending data in the this.output buffer.
if (this.output.length) {
if (this.outputData.length) {
this._flushOutput(conn);
} else if (!data.length) {
if (typeof callback === 'function') {
@ -273,9 +275,7 @@ function _writeRaw(data, encoding, callback) {
return conn.write(data, encoding, callback);
}
// Buffer, as long as we're not destroyed.
this.output.push(data);
this.outputEncodings.push(encoding);
this.outputCallbacks.push(callback);
this.outputData.push({ data, encoding, callback });
this.outputSize += data.length;
this._onPendingData(data.length);
return false;
@ -738,7 +738,7 @@ OutgoingMessage.prototype.end = function end(chunk, encoding, callback) {
// There is the first message on the outgoing queue, and we've sent
// everything to the socket.
debug('outgoing message end.');
if (this.output.length === 0 &&
if (this.outputData.length === 0 &&
this.connection &&
this.connection._httpMessage === this) {
this._finish();
@ -793,22 +793,19 @@ OutgoingMessage.prototype._flush = function _flush() {
OutgoingMessage.prototype._flushOutput = function _flushOutput(socket) {
var ret;
var outputLength = this.output.length;
var outputLength = this.outputData.length;
if (outputLength <= 0)
return ret;
var output = this.output;
var outputEncodings = this.outputEncodings;
var outputCallbacks = this.outputCallbacks;
var outputData = this.outputData;
socket.cork();
for (var i = 0; i < outputLength; i++) {
ret = socket.write(output[i], outputEncodings[i], outputCallbacks[i]);
const { data, encoding, callback } = outputData[i];
ret = socket.write(data, encoding, callback);
}
socket.uncork();
this.output = [];
this.outputEncodings = [];
this.outputCallbacks = [];
this.outputData = [];
this._onPendingData(-this.outputSize);
this.outputSize = 0;

View File

@ -69,8 +69,7 @@ server.listen(0, function() {
}
assert.strictEqual(req.output.length, 0);
assert.strictEqual(req.outputEncodings.length, 0);
assert.strictEqual(req.outputData.length, 0);
server.close();
}));