-
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
performance: changed ArrayPrototypeJoin with custom join implementation #45705
performance: changed ArrayPrototypeJoin with custom join implementation #45705
Conversation
c12fcbc
to
4ff3201
Compare
@marco-ippolito Can you remove the join implementation from |
CC @nodejs/performance |
I'm not sure overriding primordials in this way is in line with the intent of primordials. |
@mcollina v8 team has no intention of fixing this performance issue (referencing: https://bugs.chromium.org/p/v8/issues/detail?id=7420&q=array.prototype.join&can=2). I believe this is beneficial in all places of Node. |
How exactly is this implementation different from the real |
@cjihrig brings up a good point. If we are going to replace a primordial it needs to cover any edge case stipulated by the spec: https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.join For example, i think this incorrectly joins values
|
I'll create a test to cover all edge cases |
Or...... we could just use the real function. Performance isn't everything. |
I also don't think overriding primordials is the right way, it goes against the idea of primordials (to always be the guaranteed primordial value). You could create a |
Another concern is that we'll have to benchmark this with every V8 update to make sure there is still justification for the added complexity. Changes within V8 can affect performance patterns significantly. Also, I assume that the performance gain is approximately linear in the length of the array, so the effect is likely only noticeable when joining many array elements into strings. In what hot paths do we do that? |
IMO the effort here is justified. Improvements like this can lead to an overall faster core which i am in favor of. I like @aduh95 's idea of keeping the primordial as is and introducing a Fast version of it that folks can use when appropriate |
Here are the benchmarks with a variety of input sizes
|
Those numbers correspond, per operation, to saving 0.6 nanoseconds for empty arrays, 153 nanoseconds for one-element arrays, 34 nanoseconds for short arrays, and 4 microseconds for very large arrays. So my question remains the same as in my previous comment: in what hot paths do we join arrays such that saving a few CPU cycles will cause the overall performance to improve significantly? |
None of the hotter paths where join is used showed any change in the relevant benchmarks with these changes. |
I don't understand the discussion about primordials, my understnading is:
Why don't we just call our implementation in performance sensitive places without overriding the primordial? |
@benjamingr What you are describing is essentially the status quo. The slightly faster variant is only used by |
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.
Making my objection to this explicit.
It's clear that the performance gains from this PR are not worth the trouble, considering this could change with any update of v8, for this reason I'm closing this. |
As discussed in the last performance team meeting led by @anonrig, I've updated the primordial ArrayPrototypeJoin with a custom implementation because it is faster than the built-in in v8 6.0