Skip to content

Perf/arc floodfill cache - #963

Merged
louis-e merged 4 commits into
mainfrom
perf/arc-floodfill-cache
Apr 23, 2026
Merged

louis-e merged 4 commits into
mainfrom
perf/arc-floodfill-cache

Conversation

@louis-e

@louis-e louis-e commented Apr 22, 2026

Copy link
Copy Markdown
Owner

No description provided.

louis-e added 3 commits April 22, 2026 09:41
The `--benchmark` flag previously printed whole seconds, which hides
sub-second differences when evaluating micro-optimizations on small
bboxes. Switching to milliseconds keeps the same printed format but
exposes the signal needed to reason about changes that shave tens or
hundreds of ms off a run.
`FloodFillCache::get_or_compute` previously deep-cloned the cached
`Vec<(i32, i32)>` on every call. For dense forests or farmland polygons
these vecs can hold 10k-100k+ coordinates, so each handler invocation
copied tens to hundreds of kilobytes. The comment on the old clone even
acknowledged the tradeoff ("the cost is acceptable vs Arc complexity").

Wrapping the cached vecs in `Arc<Vec<_>>` replaces the copy with a
refcount bump and removes the transient duplicate allocation. For
Node/Relation fallbacks the empty result is served from a process-wide
`OnceLock` sentinel so the cold path doesn't regress either.

Call sites were updated mechanically:
- Move iterators (`for x in vec`) -> borrowing iterators (`for x in vec.iter()`)
- `for x in &vec` -> `for x in vec.iter()` (Arc derefs through method calls
  but not through `&` IntoIterator)
- buildings.rs still materializes an owned Vec because the hole-carving
  path needs `retain`; the deep copy there is cheap (building footprints
  are small) and keeps the rest of the function untouched.

Wall-clock impact on tested bboxes (Berlin/Potsdam/Grunewald) is within
measurement noise (<0.5%) — the dominant generation cost is block
placement, not cache fetch — but allocation pressure and peak memory
drop, which matters more as area size and polygon count grow. Tests
(65/65), clippy -D warnings, and fmt are clean.
The `--benchmark` flag now prints `generation_time_ms=` instead of
`generation_time=`; the workflow's grep was still looking for the old
key and would silently drop `gen_time` on every PR run. Parse the ms
value, round to the nearest whole second, and feed that into the rest
of the seconds-scale comparison logic so the verdict and PR comment
keep working unchanged.
Copilot AI review requested due to automatic review settings April 22, 2026 08:06
@github-actions

github-actions Bot commented Apr 22, 2026 •

Copy link
Copy Markdown

⏱️ Benchmark run finished in 1m 8s
🏗️ Generation time: 36s (excl. data fetching)
🧠 Peak memory usage: 1876 MB

📈 Compared against baseline: 20s
🧮 Delta: 48s
🔢 Commit: fbe93e0

🚨 This PR drastically worsens generation time.

📅 Last benchmark: 2026-04-22 11:18:31 UTC

You can retrigger the benchmark by commenting retrigger-benchmark.

@imranbadisov724-cmd

Copy link
Copy Markdown

Craftsman

Copilot AI left a comment

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.

Pull request overview

This PR improves world-generation performance by avoiding deep clones of large flood-fill coordinate lists, switching the flood-fill cache to share results via Arc, and updates the PR benchmark plumbing to report generation time in milliseconds.

Changes:

  • Store flood-fill cache entries as Arc<Vec<(i32, i32)>> and return cheap Arc clones instead of deep-copying Vecs.
  • Update element processors to iterate over cached results by reference (and explicitly materialize a Vec only where mutation is needed).
  • Emit generation_time_ms from generation code and update the PR benchmark workflow to parse/round it back to seconds for reporting.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/floodfill_cache.rs Changes cache value type to Arc<Vec<_>>, adds shared empty sentinel, updates internal iteration to account for Arc.
src/element_processing/natural.rs Adapts to Arc flood-fill results and iterates without consuming/cloning.
src/element_processing/leisure.rs Adapts to Arc flood-fill results and iterates without consuming/cloning.
src/element_processing/landuse.rs Adapts to Arc flood-fill results and iterates without consuming/cloning.
src/element_processing/historic.rs Adapts to Arc flood-fill results and iterates without consuming/cloning.
src/element_processing/highways.rs Adapts to Arc flood-fill results and iterates without consuming/cloning.
src/element_processing/buildings.rs Clones into a Vec only where ownership/mutation is required; updates loops accordingly.
src/element_processing/amenities.rs Adapts to Arc flood-fill results; updates iteration sites.
src/data_processing.rs Switches benchmark emission from seconds to milliseconds (generation_time_ms).
.github/workflows/pr-benchmark.yml Parses generation_time_ms and rounds to seconds for existing report formatting/thresholds.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/floodfill_cache.rs Outdated
Comment thread src/floodfill_cache.rs
Both the precompute path and the on-demand fallback were wrapping
`flood_fill_area`'s output in a fresh `Arc::new(...)`, so empty results
(degenerate rings, timeouts) created distinct small allocations instead
of reusing the `empty_flood_fill_result()` sentinel introduced earlier
in the PR. Consolidating both code paths so empty results always point
at the shared Arc removes the inconsistency and saves ~40 bytes per
empty cache entry.

Addresses Copilot review comments on the PR.
@louis-e

louis-e commented Apr 22, 2026

Copy link
Copy Markdown
Owner Author

retrigger-benchmark

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@louis-e
louis-e merged commit 90d47c7 into main Apr 23, 2026
6 checks passed
@louis-e
louis-e deleted the perf/arc-floodfill-cache branch April 23, 2026 19:08
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