Skip to content

Deep dive

The benchmarks section owns the numbers. This section owns the reasoning: why japes is built the way it is, what the optimisation journey taught us, and how to think about the system when you start hitting edges the tutorials don't cover.

Everything here is cross-referenced to the actual source files under ecs-core/src/main/java/zzuegg/ecs/. Every claim about a data layout, a fast-path short-circuit, or a fallback condition is verifiable against the current code. If you spot a mismatch, the code wins — the docs are describing it, not specifying it.

What to read first

  • Architecture


    Archetype + chunk storage, the EntityLocation table, why moves between archetypes are swap-removes on parallel Object[] columns. Start here if you have never read an archetype ECS internals doc before.

  • Tier-1 bytecode generation


    How a ChunkProcessor is emitted as a hidden class via java.lang.classfile, why every argument hoists to a local, and why invokevirtual is the dispatch primitive. Links to the tier fallback catalog.

  • Change tracking


    Per-component ChangeTracker, dirty bitmap + dirty list, strict > comparisons against lastSeenTick, why tick-0 is the untracked sentinel. The core of why @Filter(Changed) scales with the dirty count, not the entity count.

  • Relations


    Non-fragmenting side-table storage, Long2ObjectOpenMap primitive keys, flat TargetSlice / SourceSlice inner maps, archetype marker components, cleanup policies, PairChangeTracker. Why relations do not fragment archetypes.

  • Write-path tax


    Why @Write Mut<Position> + record Position is fundamentally more expensive than pos.x += vel.dx on a mutable POJO, what you buy for the cost, and what Valhalla could fix.

  • Valhalla investigation


    JEP 401 value records: ~2–4× faster reads at 100k, ~10% on writes, the explicit flat-array opt-in, and why it stays off by default.

  • Optimisation journey


    How the 500×2000 predator/prey cell went from 167 µs at PR-landing to 27.6 µs today. Round by round: what each fix saved, what the profile showed, and which ideas did not help.

What this section is not

It is not a tutorial, and it is not a reference for the user-facing API. For the hands-on walkthrough, read the tutorials. For a dry list of annotations and parameter types, read the cheat sheet. For throughput and latency numbers, read the benchmarks.

The pages below exist because performance work on japes has produced a coherent body of why-level knowledge — design trade-offs made, rabbit holes explored, optimisations that worked, and a few that didn't — that is neither tutorial material nor benchmark material. This is the place for it.

Reading order

The pages are written to stand alone. You can jump straight to relations or valhalla-investigation if that's what you came for. But if you are reading top-to-bottom for the first time, the natural order is:

  1. Architecture — what the storage layer looks like
  2. Tier-1 generation — how systems dispatch onto it
  3. Change tracking — what the tick-based filter machinery does
  4. Relations — the non-fragmenting pair feature
  5. Write-path tax — the API trade-off all the write-heavy benchmarks are measuring
  6. Valhalla investigation — what JEP 401 gives us today
  7. Optimisation journey — the war story