Skip to content
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

Merged
merged 1 commit into from
Mar 16, 2018
Merged

Conversation

mourner
Copy link
Contributor

@mourner mourner commented Mar 15, 2018

Removes redundant source map encoding roundtrip between magic-string and rollup, 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

Copy link
Contributor

@guybedford guybedford left a 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 = [];
Copy link
Contributor

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)

Copy link
Contributor Author

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.

Copy link
Contributor

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[] = [];
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Member

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants