-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Drop smallest inner rings for earcut performance #2622
Conversation
If you're feeling like doing something fancy, you can replace According to my unscientific tests, I think max rings will end up being something closer to 800, but let's wait to see what @jakepruitt figures out with real benchmarks. |
LGTM. Will be interested to see integration with benchmarking from @jakepruitt. Our plan is to move |
What went into the decision to simplify to a max # of rings rather than filter rings by area? I imagine the latter would result in
|
Crossposting my comment from chat, answering @lucaswoj's question: The source issue is that Earcut is slow on polygons with tons of holes, regardless of area. If we filter by area, we can’t guarantee that we’ll filter enough if the threshold is low, and that we won't introduce unwanted visual change if the threshold is high. E.g. I had to bump the area threshold pretty high in a recent test of Streets (800 in tile coords), but this may be too high for other datasets. So we’ll guard against the source issue with Earcut, and leave the noise filtering as responsibility of the dataset designer. |
Once we bump |
I'm going to take a quick look at benchmarks using https://github.com/mourner/quickselect instead of |
@lucaswoj in theory, it should be about 5-7 times faster for a 500-hole polygon, but if the total sort is just a few millisecond, it probably doesn't matter much. Although worth pointing out that quickselect is already in the dep tree through supercluster->kdbush, so it won't add to the bundle size. |
polygons[j] = truncated.concat(polygon.slice(0, maxRings - 1)); | ||
if (polygons[j].length <= maxRings) continue; | ||
quickselect(polygons[j], maxRings - 1, 1, polygon.length - 1, sortByArea); | ||
polygons[j] = polygon.slice(0, maxRings); |
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 seems that the 2nd arg to quickselect
should be just maxRings
— k
is position independent of left
.
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.
Got it! I was a little unsure of the relationship between k
and maxRings
from the quickselect
docs.
🚢 on 🍏 @mourner @yhahn @jakepruitt? |
classifyRings()
EARCUT_MAX_RINGS
(currently set to 100)Next actions
EARCUT_MAX_RINGS
valuecc @jakepruitt @jfirebaugh