Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2ea8885

Browse files
committedOct 2, 2023
perf: optimize Writable
PR-URL: nodejs#50012
1 parent 85c09f1 commit 2ea8885

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed
 

‎lib/internal/streams/writable.js

+18-9
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ const kWriteCb = 1 << 26;
108108
const kExpectWriteCb = 1 << 27;
109109
const kAfterWriteTickInfo = 1 << 28;
110110
const kAfterWritePending = 1 << 29;
111+
const kEmptyBuffer = 1 << 30;
111112

112113
// TODO(benjamingr) it is likely slower to do it this way than with free functions
113114
function makeBitMapDescriptor(bit) {
@@ -339,7 +340,7 @@ function WritableState(options, stream, isDuplex) {
339340
function resetBuffer(state) {
340341
state.buffered = [];
341342
state.bufferedIndex = 0;
342-
state.state |= kAllBuffers | kAllNoop;
343+
state.state |= kAllBuffers | kAllNoop | kEmptyBuffer;
343344
}
344345

345346
WritableState.prototype.getBuffer = function getBuffer() {
@@ -523,6 +524,7 @@ function writeOrBuffer(stream, state, chunk, encoding, callback) {
523524

524525
if ((state.state & (kWriting | kErrored | kCorked | kConstructed)) !== kConstructed) {
525526
state.buffered.push({ chunk, encoding, callback });
527+
state.state &= ~kEmptyBuffer;
526528
if ((state.state & kAllBuffers) !== 0 && encoding !== 'buffer') {
527529
state.state &= ~kAllBuffers;
528530
}
@@ -591,8 +593,9 @@ function onwrite(stream, er) {
591593
// Avoid V8 leak, https://github.com/nodejs/node/pull/34103#issuecomment-652002364
592594
er.stack; // eslint-disable-line no-unused-expressions
593595

594-
if (!state.errored) {
595-
state.errored = er;
596+
if ((state.state & kErrored) === 0) {
597+
state[kErroredValue] = er;
598+
state.state |= kErrored;
596599
}
597600

598601
// In case of duplex streams we need to notify the readable side of the
@@ -607,12 +610,12 @@ function onwrite(stream, er) {
607610
onwriteError(stream, state, er, cb);
608611
}
609612
} else {
610-
if (state.buffered.length > state.bufferedIndex) {
613+
if ((state.state & kEmptyBuffer) === 0) {
611614
clearBuffer(stream, state);
612615
}
613616

614617
if (sync) {
615-
const needDrain = state.length === 0 && (state.state & kNeedDrain) !== 0;
618+
const needDrain = (state.state & kNeedDrain) !== 0 && state.length === 0;
616619
const needTick = needDrain || (state.state & kDestroyed !== 0) || cb !== nop;
617620

618621
// It is a common case that the callback passed to .write() is always
@@ -625,7 +628,9 @@ function onwrite(stream, er) {
625628
state.state |= kAfterWritePending;
626629
} else {
627630
state.pendingcb--;
628-
finishMaybe(stream, state, true);
631+
if ((state.state & kEnding) !== 0) {
632+
finishMaybe(stream, state, true);
633+
}
629634
}
630635
} else if ((state.state & kAfterWriteTickInfo) !== 0 &&
631636
state[kAfterWriteTickInfoValue].cb === cb) {
@@ -636,7 +641,9 @@ function onwrite(stream, er) {
636641
state.state |= (kAfterWritePending | kAfterWriteTickInfo);
637642
} else {
638643
state.pendingcb--;
639-
finishMaybe(stream, state, true);
644+
if ((state.state & kEnding) !== 0) {
645+
finishMaybe(stream, state, true);
646+
}
640647
}
641648
} else {
642649
afterWrite(stream, state, 1, cb);
@@ -668,7 +675,9 @@ function afterWrite(stream, state, count, cb) {
668675
errorBuffer(state);
669676
}
670677

671-
finishMaybe(stream, state);
678+
if ((state.state & kEnding) !== 0) {
679+
finishMaybe(stream, state, true);
680+
}
672681
}
673682

674683
// If there's something in the buffer waiting, then invoke callbacks.
@@ -692,7 +701,7 @@ function errorBuffer(state) {
692701

693702
// If there's something in the buffer waiting, then process it.
694703
function clearBuffer(stream, state) {
695-
if ((state.state & (kDestroyed | kBufferProcessing | kCorked)) !== 0 ||
704+
if ((state.state & (kDestroyed | kBufferProcessing | kCorked | kEmptyBuffer)) !== 0 ||
696705
(state.state & kConstructed) === 0) {
697706
return;
698707
}

0 commit comments

Comments
 (0)
Please sign in to comment.