Skip to content

Use cached hit box bounds in the spatial hash - #2900

Merged
pvcraven merged 1 commit into
developmentfrom
perf/spatial-hash-cached-bounds
Oct 1, 2026
Merged

pvcraven merged 1 commit into
developmentfrom
perf/spatial-hash-cached-bounds

Conversation

@pvcraven

@pvcraven pvcraven commented Oct 1, 2026

Copy link
Copy Markdown
Member

Summary

SpatialHash._get_cell_bounds() (added in #2893) scanned a sprite's adjusted hit box points itself to find which grid cells it covers. It now reads HitBox.get_adjusted_bounds() (added in #2894) instead. That method caches the bounds until the points change, and collision checks already use it, so a sprite's bounds are now computed once and shared.

The results are identical: same minimum and maximum, same trunc and cell hashing. The existing test_cell_bounds_match_sprite_bounds (including rotated sprites) and the spatial hash tests all pass unchanged.

Benchmarks

µs per call, best of 21 × 200,000 calls, 3 alternating before/after rounds (range shown):

Case Before After
get_sprites_near_sprite, sprite that hasn't moved 1.77–2.12 1.06–1.25
add + remove, sprite that hasn't moved 2.40–2.45 1.60–1.66
get_sprites_near_sprite, sprite moving each call 4.21–4.27 4.24–4.38
moving a sprite in a spatial-hashed list 3.99–4.77 4.34–4.77
move a hashed sprite, then check_for_collision 9.06–10.57 9.30–9.58

A sprite that hasn't moved gets its bounds straight from the cache, so it's about 33–40% faster. A moving sprite has its points recalculated either way, so those cases are unchanged within noise.

benchmarks/spatial_hash/queries.py still shows no bucket growth (102 buckets before and after querying a 20000×20000 area).

Tests

  • Spatial hash, sprite and hit box tests: 123 passed. Full unit suite: 1103 passed. The 3 failures are the render tests that only fail on my machine.
  • Ruff is clean, and mypy reports no errors in spatial_hash.py.

🤖 Generated with Claude Code

SpatialHash._get_cell_bounds() scanned the hit box's adjusted points
itself. It now reads HitBox.get_adjusted_bounds(), which caches the
bounds until the points change and shares them with collision checks.

For sprites that haven't moved since their bounds were last needed,
querying is ~40% faster and add + remove ~33% faster. Moving sprites
are unchanged, since their points are recalculated either way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pvcraven
pvcraven merged commit d71fba2 into development Oct 1, 2026
7 checks passed
@pvcraven
pvcraven deleted the perf/spatial-hash-cached-bounds branch October 1, 2026 15:57
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