Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Performance roadmap

The originally-planned tiers all landed inside FastGame + Propagator. FastSolver solves a 100×100 Akari in ~42 ms; StandardGrader grades the same in ~210 ms. See the Fast solver chapter for the full optimization log — what worked, what was reverted, and what’s still open.

The ideas that landed:

  • Region indices cached once at construction. Each constraint resolves its Region to a Vec<usize> of dense coord indices in Propagator::region_indices; the hot path walks the slice directly with candidates[i] access.
  • First-class LOS / ray substrates. Region::Los, Region::LosCross, and Region::Neighbors4 resolve natively via puzzle.substrate().blocks_los(r, c) — a direct read on the cells grid (Material::Wall blocks, Floor and Hole pass through), no trait-method dispatch.
  • Per-constraint aggregates. Each constraint caches committed_with_mark / possible_with_mark; apply/undo maintain them; forced_moves_at reads them in O(1).
  • Per-cell counters (Tier 3, the big one). Puzzles declare named counters via Puzzle::cell_counters(); the propagator maintains them through apply/undo via precomputed inverse- reach. Rule::CellMin { counter, min } propagates cell-by-cell through a dirty-cells queue instead of riding the AC-3 worklist.
  • Bitmask candidates. Per-coord u32, one bit per mark in the puzzle’s universe. Apply / undo are mask & !bit / mask | bit.
  • MRV trial ordering + intra-sweep propagation in trial-1.
  • LTO=fat + codegen-units=1 in release.

Still open: fused substrate-aware updates (a move that walks a ray AND emits forced moves on those same cells, in one pass), MAC / GAC / AC-2001, trial-2/N, smarter branch heuristics, parallelism in the solve loop, WASM measurement.