Skip to content

Enhance getVisibleCoordinates performance - #7956

Closed
pakastin wants to merge 1 commit into
mapbox:masterfrom
pakastin:master
Closed

pakastin wants to merge 1 commit into
mapbox:masterfrom
pakastin:master

Conversation

@pakastin

@pakastin pakastin commented Feb 27, 2019

Copy link
Copy Markdown
Contributor

I started to profile panning/zooming performance and realized getVisibleCoordinates function is pretty heavy. Preallocating an array and using a single for-loop while adding posMatrix simultaneously makes it faster.

@pakastin

pakastin commented Feb 27, 2019

Copy link
Copy Markdown
Contributor Author

Here's relevant jsperf: https://jsperf.com/for-loop-vs-array-prototype-map-bench

@mourner mourner left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I doubt the JSPerf is representative here, because there are significant differences — 1) the number of coordinates is usually very low (e.g. 6 tiles is typical for a full-screen map), vs 10000 in the bench; 2) arrays of objects like in this case have very different perf characteristics than arrays of numbers, which are treated differently by JS engines. 3) Microbenchmarks can be misleading — e.g. 1, 2.

Unless you can demonstrate measurable performance difference in GL JS specifically, I'd be inclined to keep the code more terse and simple.

@pakastin

Copy link
Copy Markdown
Contributor Author

Wonder why that function took longest scripting time inside Chrome dev tools performance tab, and after this I got it down to like 10th. I try to run some benchmarks with and without.

@pakastin

pakastin commented Feb 27, 2019

Copy link
Copy Markdown
Contributor Author

Didn't realize the arrays are so small, so you're probably right! Maybe need to profile getRenderableIds instead.. 🤔

@pakastin pakastin closed this Feb 27, 2019
@mourner

mourner commented Feb 27, 2019

Copy link
Copy Markdown
Member

Wonder why that function took longest scripting time inside Chrome dev tools performance tab, and after this I got it down to like 10th. I try to run some benchmarks with and without.

The profiling results often fluctuate depending on what's happening in the background, what exactly you did during the profiling, etc. Here's a quick result I got zooming/panning for a few seconds:

image

@pakastin

Copy link
Copy Markdown
Contributor Author

Yeah, that might be the case – i'll keep on investigating, thanks! 😎

@andycalder

Copy link
Copy Markdown
Contributor

@pakastin it's interesting that you raised this because I've also noticed getVisibleCoordinates being really heavy in certain situations. I tested the satellite debug map with 60 degree pitch to maximise the number of tiles (raster maps need 4x as many tiles). Looking in the flamegraph, you can see getVisibleCoordinates taking up a significant portion of frame time. The below frame is pretty typical for me:

flamegraph

I don't have a solution but I agree that it might be worth investigating.

@pakastin

pakastin commented Mar 1, 2019

Copy link
Copy Markdown
Contributor Author

Yeah, I too have quite many layers here:
https://beta.aviamaps.com/map

I was wondering did I really profile so wrong 😄

@pakastin

pakastin commented Mar 1, 2019

Copy link
Copy Markdown
Contributor Author

Well, this PR would make it faster when there’s many iterables.. 😎

@asheemmamoowala

Copy link
Copy Markdown
Contributor

@pakastin @mourner on a pitched satellite map, I am seeing a consistent reduction in getVisibleCoordinates performance from 3-7ms, to 0.3-1.2ms.

@pakastin

pakastin commented Mar 4, 2019

Copy link
Copy Markdown
Contributor Author

Yeah, in some other circumstances that would be just micro-optimization, but when you have constant 60 fps budget, every fraction of a millisecond counts..

@mourner

mourner commented Mar 5, 2019

Copy link
Copy Markdown
Member

I've also made a similar change as a part of #7971 — can you check this one too?

@andycalder

Copy link
Copy Markdown
Contributor

I've been testing this by panning a pitched satellite map around for a few seconds and I'm unable to see any significant performance improvement relative to master. Dev tools is telling me that almost all of the time is spent on getRenderableIds() and calculatePosMatrix() so I'm not sure how refactoring the loop is going to help.

screenshot

@asheemmamoowala do you mean to say that the pitched map reduces performance relative to a flat map? Or that this PR increases performance relative to master?

@andycalder

Copy link
Copy Markdown
Contributor

@mourner I did a quick test of #7971 and it seems to be the same. No significant change in performance.

@asheemmamoowala

Copy link
Copy Markdown
Contributor

@asheemmamoowala do you mean to say that the pitched map reduces performance relative to a flat map? Or that this PR increases performance relative to master?

The fix here improves performance relative to master, i.e. it reduces the time spent in getVisibleCoordinates.

@pakastin

Copy link
Copy Markdown
Contributor Author

It’s almost impossible that it would be slower after optimizations, since for-loop does less than array prototype methods.

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.

4 participants