Uh oh!
There was an error while loading. Please reload this page.
buffer: port byteLengthUtf8 to JavaScript - #18356
Conversation
Prior to this change the majority of the time spent when calling `Buffer.byteLength` was spent on crossing JS->C++ boundary. This change move the function to JavaScript, making it much faster.
2c35736 to
de2287eComparejasnell
commented
Jan 24, 2018
Performance boost I assume? |
indutny
commented
Jan 24, 2018
@jasnell forgot to write about it. It is 2x faster on small strings, but is slower on large ones. This is the reason for awaiting for v8 update. |
jasnell
commented
Jan 24, 2018
If the perf loss on the large ones is significant, perhaps split the difference and use the js method for short ones and fallback on longer? |
indutny
commented
Jan 24, 2018
Perhaps, but I'd rather wait for V8 update. We've been living with C++ code for awhile now. |
indutny
commented
Jan 24, 2018
Added expected V8 version. |
| // NOTE: 0 <= code <= 0xffff | ||
| var code = string.charCodeAt(i); | ||
| if (code <= 0x7f) { | ||
| len++; |
There was a problem hiding this comment.
len += 1; for consistency with line 348.
indutny
commented
Mar 7, 2018
Looks like this might be ready after #19201 lands. |
indutny
commented
Mar 7, 2018
Hm... it is still slow even on V8 6.6. cc @bmeurer Here's the benchmark that I used: https://gist.github.com/indutny/0fe9a3ed3b93d558a60deacefc37e378 . The results are: |
bmeurer
commented
Mar 8, 2018
You need to pass |
indutny
commented
Mar 8, 2018
@bmeurer tbh, I don't see a reason for it to be slow. The performance seems to be dependent on string flattening, which apparently doesn't happen in JS case. Could it potentially happen at all? |
bmeurer
commented
Mar 8, 2018
@indutny The reason is that String#charCodeAt() has to dispatch on string type all the time (potentially 8 different types for the "fast case"), whereas the C++ code just accesses the character data. We could try to make TurboFan a bit smarter here if we find a way to do the flattening (which is indeed happening here) in the peeled loop iteration only and then have only sequential one-byte string access inside the actual loop. But that's work that needs to be done and I'm a bit worried that we over-optimize for the particular example. |
bmeurer
commented
Mar 8, 2018
BTW V8 tip-of-tree should be faster already thanks to the recent work by @sigurdschneider. |
indutny
commented
Mar 8, 2018
bmeurer
commented
Mar 8, 2018
Not saying it's not worth it, but it's definitely not high priority. Did you check with tip-of-tree? And |
indutny
commented
Mar 8, 2018
@bmeurer I checked |
srl295
left a comment
There was a problem hiding this comment.
seems ok (did not check the math in detail)… might also compare to http://source.icu-project.org/repos/icu/trunk/icu4c/source/common/unicode/utf8.h which has been highly optimized
BridgeAR
commented
Apr 10, 2018
Should this stay open? It seems like the JS implementation can not get as fast as the C++ implementation. Ping @indutny |
BridgeAR
commented
Apr 16, 2018
Closing as this does not seem like it is the right approach in JS. @indutny please reopen in case you disagree and want to continue working on this. |
indutny
commented
Apr 16, 2018
I think we could potentially apply it to short strings. Anyone up to do some benchmarks? |
Please don't land this PR yet. There is a missing V8 optimization, that is going to be available soon
in V8 6.6.
Prior to this change the majority of the time spent when
calling
Buffer.byteLengthwas spent on crossing JS->C++ boundary. Thischange move the function to JavaScript, making it much faster.
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passesAffected core subsystem(s)
buffer