Skip to content

perf(correct): find the closing point of a traced ring by hash lookup - #974

Open
dktue wants to merge 1 commit into
systemed:masterfrom
dktue:perf/correct-closing
Open

dktue wants to merge 1 commit into
systemed:masterfrom
dktue:perf/correct-closing

Conversation

@dktue

@dktue dktue commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Gain: the two slowest planet relations 43.9 → 3.9 s (−91%) and 53.8 → 3.2 s (−94%); extract user CPU −20%. On the planet, measured together with the ring-assignment PR #975: relations phase 105 → 61 s (−42%), total wall 1659 → 1620 s (−2.4%). Output identical.

make_valid repairs self-intersecting rings with geometry::correct() in include/geometry/correct.hpp. dissolve_generate_rings traces each repaired ring point by point, and after every new point is_closed scanned the whole ring traced so far for an earlier point equal to the new one. That is quadratic in the ring's size, and on a few huge planet relations it dominates.

This PR keeps a hash map from each traced point to its position in the ring. A ring's points are distinct until it closes, so a point found in the map closes it, and the points before the earlier occurrence are dropped as before. The test was exact equality (comparable_distance == 0) and stays exact; + 0.0 makes -0.0 and 0.0 hash alike, as they compared equal before.

Equivalence

The same test program, compiled once with the old and once with the new header, repaired 2,000 random self-intersecting polygons (continuous and grid coordinates, with and without holes; 1,999 non-empty results). The WKT output of both is byte-identical. Germany output (compare_area, per-tile area/length per layer and tag group) is identical too; only poi differs, as between identical runs.

Speed, extract with the five slowest planet relations

relation before after
r20516020 wood (193 outer, 210 inner ways) 43.9 s 3.9 s (−91%)
r13985343 Lake Nasser (878 outer, 6,758 inner) 53.8 s 3.2 s (−94%)

User CPU of the extract run −20%. For the planet, see the ring-assignment PR #975, measured together: the relations phase drops from 105 s to 61 s.

🤖 Generated with Claude Code

dissolve_generate_rings scanned the whole traced ring for every new point
to see whether it closes the ring, which is quadratic in the ring size.
Keep a map from point to position instead; the closing test stays exact.

Output identical (2,000 random self-intersecting polygons, old vs new
header; Germany compare_area). Slowest planet relations: wood r20516020
43.9 -> 3.9 s (-91%), Lake Nasser 53.8 -> 3.2 s (-94%).
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.

1 participant