-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
Buffer bounds checks slow (writeUInt8 with noAssert = false) #11245
Comments
Pull requests are always welcome, but since brackets do not throw on an invalid index, there would have to be explicit range checking (maybe even for performance reasons?). |
I wonder if anyone relies on the exceptions thrown by |
I decided to run some benchmarks, some experiments and some more benchmarks on my 64-bit Windows 10 machine. Node's own benchmarks confirm that The checkInt function that's called when Removing the Uint8Array check (and leaving the other two), however, made a huge difference: Without the Uint8Array check, I have no idea why exactly this check was necessary in the first place (it was added in one huge commit), so I propose the following course of action:
/cc @nodejs/collaborators |
This makes write[U]Int* operations on Buffer with `noAssert=false` about 3 times faster. PR-URL: #11324 Refs: #11245 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com>
# v7.7.1
$ node buftest.js
Assigning buf[i], buf[i+1]: 442.359ms
buf.writeUInt16LE, noAssert: 404.190ms
buf.writeUInt16LE, without noAssert: 11098.851ms
Assigning buf[i]: 253.650ms
buf.writeUInt8, noAssert: 288.419ms
buf.writeUInt8, without noAssert: 11238.774ms
# master
$ ./node buftest.js
Assigning buf[i], buf[i+1]: 541.285ms
buf.writeUInt16LE, noAssert: 416.756ms
buf.writeUInt16LE, without noAssert: 1000.491ms
Assigning buf[i]: 300.127ms
buf.writeUInt8, noAssert: 286.881ms
buf.writeUInt8, without noAssert: 830.433ms The slow-down is not nearly as drastic. Closing. |
The
write
family of functions onBuffer
objects (buf.writeUInt8
etc.) have a lot of overhead whennoAssert
isn't set to true -- much more than I would normally expect from a bounds check.Here are some timings I got for filling a 100MB buffer (Node 7.5.0 on 64-bit Linux):
I had a lot of timing variation, so I don't think the indexed-vs-writeUInt8 differences are meaningful. This might be because we're down to about 10 CPU cycles per iteration. My bug report is about the unexpected order-of-magnitude difference when
noAssert
is not enabled.Benchmark code:
Related: #11244 ("Unclear if Buffer buf[i] is bounds-checked"). If
buf[i]
is indeed bounds-checked, then surely we should be able to achieve the same performance withnoAssert = false
?The text was updated successfully, but these errors were encountered: