-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Faster source map generation #2062
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.
Excellent work @mourner, I left a couple of comments re array allocation that may or may not have any tangible effect.
@@ -49,23 +48,20 @@ class Link { | |||
const sourcesContent: string[] = []; | |||
const names: string[] = []; | |||
|
|||
const mappings = this.mappings.map(line => { | |||
const mappings = []; |
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.
It may help performance to initialize the array length there? new Array(this.mappings.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.
No, V8 is very good at growing arrays. Besides, new Array(length)
creates a sparse array (all items are undefined), which is a perf antipattern.
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 right ok.
const mappings = this.mappings.map(line => { | ||
const mappings = []; | ||
|
||
for (const line of this.mappings) { | ||
const tracedLine: SourceMapSegmentVector[] = []; |
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.
And possibly here as well, although it may not make that much of a difference, but at least avoids possible reallocation cost.
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.
In my experience building computational geometry libraries that process arrays with millions of items, it's safe to initialize an empty array without worrying about performance. The only case where you want (and forced to) to preallocate is with typed arrays.
I also prefer for ... of
over forEach
/map
because it avoids new closures. TypeScript converts them into simple for
loops.
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.
TypeScript converts them into simple for loops
Ah right, I stumbled about this once but forgot later. Very nice, so there is no performance overhead checking the array iterator.
Removes redundant source map encoding roundtrip between
magic-string
androllup
, which should speed up source map generation by up to 40%. For example, Mapbox GL JS bundle takes ~400-500ms less time after this PR.Also contains some minor code clean up in
collapseSourcemaps.ts
that I forgot to commit separately.Fixes #2061. cc @guybedford @lukastaegert