-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
stream: skip chunk validation for Buffers #10580
Conversation
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM after CI passes.
@Fishrock123 Actually, It's also avoiding a function call in case |
33dbb04
to
f9ca2d8
Compare
f9ca2d8
to
1099c80
Compare
Added another optimization that provides an additional ~30% increase. CI again: https://ci.nodejs.org/job/node-test-pull-request/5669/ |
@nodejs/streams |
Oh, maybe I was thinking about |
if (chunk instanceof Buffer) | ||
encoding = 'buffer'; | ||
function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { | ||
if (!isBuf) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mscdex could chunk
have changed before this is called?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. writeOrBuffer()
is only called by write()
and validChunk()
does not return a modified chunk or anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code in itself is fine, and it's a very good catch. However the title in the PR and the commit message does not match the content.
The check is not skipped, it is just executed once.
// and we're not in objectMode, then that's an error. | ||
// Otherwise stream chunks are all considered to be of length=1, and the | ||
// watermarks determine how many objects to keep in the buffer, rather than | ||
// how many bytes or characters. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should add back some comment here, explaining this change. validChunk
now only checks if a chunk is valid when it is not a Buffer
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed the comments here because they either duplicated what the inline comments already said or had nothing to do with validChunk()
('Otherwise stream chunks ...').
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even the inline comments are pretty redundant as they just explain what the simple code below it is doing, not worth keeping IMHO. I have added a new comment above the function definition now.
I'm not sure what you mean by this. |
I mean that the |
|
||
function main(conf) { | ||
const n = +conf.n; | ||
const b = new Buffer(1024); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is going to be kept as new Buffer(...)
, can you add a comment explaining why (e.g. to allow comparison with older Node.js versions). That said, I'd prefer this to be changed to Buffer.alloc(...)
given that Node.js 4 is the lowest currently supported version and the new constructors have been backported to that version already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
typeof chunk !== 'string' && | ||
chunk !== undefined && | ||
!state.objectMode) { | ||
} else if (typeof chunk !== 'string' && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would switching to Buffer.isBuffer()
have the same performance profile as instanceof
? By removing the instanceof Buffer
check here, this becomes a semver-major. If we can switch to Buffer.isBuffer()
and still get a performance boost, then this can be semver-patch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jasnell this PR is not removing the check (see my comment). It is still doing it, just in a different way. I would flag it semver-minor, and it can even be backported to v4 and v6.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Buffer.isBuffer()
is just an instanceof
check, so that would not help. Also, @mcollina is correct, we're just avoiding duplicate instanceof
s since it was already being done in write()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah.. lol, forgot about that :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mscdex that's my point on the review. "remove duplicate instanceof
checks" should be a good commit message/pr title.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mcollina It's not just that though, for example it would have also checked for null
before getting to the second instanceof
check. Anyway, I've changed the commit message. Let me know if it's more suitable.
|
||
function main(conf) { | ||
const n = +conf.n; | ||
const b = new Buffer(1024); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we use Buffer.alloc
or Buffer.allocUnsafe
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just copied from one of the other buffer benchmarks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
1099c80
to
bb29b22
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
These changes result in ~50% improvement in the included benchmark. PR-URL: nodejs#10580 Reviewed-By: Сковорода Никита Андреевич <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
bb29b22
to
0a93728
Compare
These changes result in ~50% improvement in the included benchmark. PR-URL: nodejs#10580 Reviewed-By: Сковорода Никита Андреевич <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
These changes result in ~50% improvement in the included benchmark. PR-URL: nodejs#10580 Reviewed-By: Сковорода Никита Андреевич <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
These changes result in ~50% improvement in the included benchmark. PR-URL: nodejs#10580 Reviewed-By: Сковорода Никита Андреевич <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
These changes result in ~50% improvement in the included benchmark. PR-URL: nodejs#10580 Reviewed-By: Сковорода Никита Андреевич <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
@mscdex how long should these bake before LTS? |
I'm 👍 , but I think we should assemble a release of |
I'm 👍 on backporting to v6. |
These changes result in ~50% improvement in the included benchmark. PR-URL: #10580 Reviewed-By: Сковорода Никита Андреевич <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
These changes result in ~50% improvement in the included benchmark. PR-URL: #10580 Reviewed-By: Сковорода Никита Андреевич <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
These changes result in ~50% improvement in the included benchmark. PR-URL: #10580 Reviewed-By: Сковорода Никита Андреевич <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
These changes result in ~50% improvement in the included benchmark. PR-URL: #10580 Reviewed-By: Сковорода Никита Андреевич <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
These changes result in ~50% improvement in the included benchmark. PR-URL: #10580 Reviewed-By: Сковорода Никита Андреевич <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
These changes result in ~50% improvement in the included benchmark. PR-URL: nodejs/node#10580 Reviewed-By: Сковорода Никита Андреевич <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: James M Snell <[email protected]>
These changes result in ~50% improvement in the included benchmark:
/cc @nodejs/streams
CI: https://ci.nodejs.org/job/node-test-pull-request/5668/
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)