-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
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
perf: Improve builders of @babel/types
#16870
base: main
Are you sure you want to change the base?
Conversation
Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/58063 |
// For performance | ||
const subKey: any = { | ||
toString() { | ||
return `${key}[${i}]`; | ||
}, | ||
}; |
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.
Could you explain this change? I would expect allocating an object to be bad, since then it needs to be garbage collected.
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 this have the same effect?
if (i < val.length) {
const subKey = `${key}[${i}]`;
do {
callback(node, subKey, v);
childValidator(node, subKey, v);
} while (++i < val.length);
}
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 performance gap here seems to come from frequently generating strings and not using them, and subKey
is only used when an exception is thrown.
I allocated an object instead of concatenating countless unused strings, so it will be faster.
Would this have the same effect?
subKey
should be dynamic along with i
. :)
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.
Oh ok. If we want to do this, we should update key
's type to be string | { toString(): string }
. Or maybe just make it key: () => 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.
I tried key: () => string
, which doesn't work for a static key
for a non-array element. I'll try string | { toString(): string }
.
Co-authored-by: Nicolò Ribaudo <nicolo.ribaudo@gmail.com>
// For performance | ||
const subKey = { | ||
toString() { | ||
return `${key}[${i}]`; | ||
}, | ||
}; |
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.
Can you expand a bit the comment here?
- concatenating the strings is expensive because we are actually concatenating a string and a number, so V8 cannot just create a "rope string" but has to allocate memory for the string resulting from the number
- this string is very rarely used, only in error paths, so we can skip the concatenation cost in most cases
Fixes #1, Fixes #2
This improves performance by about 1x.