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

Use a special data structure for transferring feature id maps to the main thread #7132

Merged
merged 5 commits into from
Aug 18, 2018

Conversation

mourner
Copy link
Member

@mourner mourner commented Aug 15, 2018

Fixes #7110 (not fully but almost there); a part of addressing #7011. An alternative to #7015.

Instead of a struct array that gets deserialized into a JS object on the main thread (which is expensive and causes stutter), this PR introduces a special data structure for storing feature id to position mappings which consists of two typed arrays — ids and positions. Both get sorted by id before transferring, which allows using binary search on the main thread for id lookup (avoiding building a JS object completely).

This brings TTFR for the difficult #7110 case to nearly pre-feature-state levels (10-20% slower instead of 4x slower), while also theoretically reducing stutter (due to elimination of big non-transferable id maps which are very expensive to clone when sending to the main thread). @ryanbaumann's feature state choropleth also speeds a little (20% faster to fully load).

Note that I used Uint32Array for buffer offsets instead Uint16 (like in #7015) because the latter overflows (e.g. on Ryan's example).

Launch Checklist

  • briefly describe the changes in this PR
  • write tests for all new functionality
  • document any changes to public APIs
  • post benchmark scores
  • manually test the debug page

@jfirebaugh
Copy link
Contributor

Can we avoid even generating an id map for layers that don't use any feature-state expressions?

@asheemmamoowala
Copy link
Contributor

@jfirebaugh that is possible, but would require re-building the paint arrays, or building the map some other way if setPaintProperty is used with a feature-state expression.

@mourner
Copy link
Member Author

mourner commented Aug 16, 2018

@jfirebaugh we should definitely explore this, but independently of this PR (which will be a benefit in any case I think).

@jfirebaugh
Copy link
Contributor

Did none of our existing benchmarks detect the performance regression in #7110? What would it take to have a benchmark that can alert us to regressions in TTFR?

}

this._bufferOffset = newLength;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _bufferOffset needs to move forward after each feature is added, even if there is no id attribute. For tiles that have features mixed with/without ids, the current code will assign all vertex array positions between two features with ids.
Here's an example of this on a symbol layer:
screen shot 2018-08-16 at 12 02 58 pm

}
}
const positions = [];
while (this.ids[i] === id) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to add a note here that it relies on sorting the ids and positions arrays as part of serialization. Maybe include a test to ensure that serialize sorts these.

@mourner
Copy link
Member Author

mourner commented Aug 16, 2018

Did none of our existing benchmarks detect the performance regression in #7110? What would it take to have a benchmark that can alert us to regressions in TTFR?

@jfirebaugh it might help to add a worker roundtrip benchmark that parses a few heavy tiles and then just sends them back and forth between the main thread and a worker (to specifically target postMessage performance and transferring). Let's do it in a follow-up PR.

@jfirebaugh
Copy link
Contributor

@mourner We should have a benchmark that shows this change is a performance benefit though. (And unit tests.)

@mourner
Copy link
Member Author

mourner commented Aug 17, 2018

Results for the new WorkerTransfer benchmark:

image

Copy link
Contributor

@asheemmamoowala asheemmamoowala left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

Copy link
Contributor

@jfirebaugh jfirebaugh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏

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.

3 participants