Skip to content

Speed up IslandPruningModule with a cheaper edge-traversability check - #8028

Merged
leonardehrenfried merged 9 commits into
opentripplanner:dev-2.xfrom
leonardehrenfried:island-pruning-benchmark
Oct 1, 2026
Merged

leonardehrenfried merged 9 commits into
opentripplanner:dev-2.xfrom
leonardehrenfried:island-pruning-benchmark

Conversation

@leonardehrenfried

@leonardehrenfried leonardehrenfried commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

Summary

Speeds up IslandPruningModule (the graph-builder step that detects small disconnected "islands" of the street graph and prunes or no-thru's them) by replacing the per-edge StreetEdge.traverse() call in collectNeighbourVertices() with the existing, allocation-free StreetEdge.canTraverse(TraverseMode) permission check. Benchmarked on a full Norway OSM extract (3 runs on each side), this is a reproducible ~7-8% speedup for island pruning, with identical output (same edges removed/restricted/marked no-thru).

Also adds a standalone benchmark, IslandPruningBenchmark (in test-fixtures, not run by CI), that downloads a full-country OSM extract, builds the street graph, and times island pruning in isolation - the existing unit tests only exercise small fixtures, and this module is specifically CPU/memory sensitive at country scale.

Issue

No linked issue - this is a self-contained performance cleanup.

Motivation: IslandPruningModule.collectNeighbourVertices() calls e.traverse(s0) for every outgoing edge of every street vertex, once per travel mode (WALK/BICYCLE/CAR), purely to learn whether an edge is usable and which vertex it leads to - the resulting State's cost/weight is discarded. traverse() still allocates a StateEditor, computes walk/bike speed and slope-adjusted cost, and builds a State object for every edge, none of which this module needs.

How the code works / approach: StreetEdge already exposes canTraverse(TraverseMode), a permission + barrier-vertex check with no allocation. collectNeighbourVertices() now uses that directly for plain StreetEdge/AreaEdge instances (keeping the same "dismount and walk the bike" fallback StreetEdge.traverse() applies for BICYCLE mode), and only falls back to a real traverse() call for edge types that don't behave like a simple permission-gated street edge (escalators, pathways, vehicle rental/parking edges).

@leonardehrenfried
leonardehrenfried requested a review from a team as a code owner September 22, 2026 12:46
@leonardehrenfried leonardehrenfried added the !Optimization The feature is to improve performance. label Sep 22, 2026
@codecov

codecov Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 88.46154% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.62%. Comparing base (161c13d) to head (e2677ce).
⚠️ Report is 146 commits behind head on dev-2.x.

Files with missing lines Patch % Lines
...lder/module/islandpruning/IslandPruningModule.java 88.46% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@              Coverage Diff              @@
##             dev-2.x    #8028      +/-   ##
=============================================
+ Coverage      74.57%   74.62%   +0.04%     
- Complexity     22708    22880     +172     
=============================================
  Files           2514     2533      +19     
  Lines          87945    88526     +581     
  Branches        8690     8752      +62     
=============================================
+ Hits           65589    66064     +475     
- Misses         19307    19394      +87     
- Partials        3049     3068      +19     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

}
var visibilityVertices = StreamUtils.ofIterable(graph.findEdges(AreaEdge.class)).collect(
Collectors.toSet()
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It looks like you forgot to actually fetch the visibilityVertices?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Okay, that was pretty embarrassing.

In order for this to not happen again I added a module test for this very feature and fixed the code.

@leonardehrenfried
leonardehrenfried added this pull request to the merge queue Oct 1, 2026
Merged via the queue into opentripplanner:dev-2.x with commit a408865 Oct 1, 2026
8 of 10 checks passed
@leonardehrenfried
leonardehrenfried deleted the island-pruning-benchmark branch October 1, 2026 13:40
t2gran pushed a commit that referenced this pull request Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

!Optimization The feature is to improve performance.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants