Table of Contents

Performance Patterns

This page captures the runtime performance techniques used in Ghost.Entities and how to apply them.

Data Layout

  • Archetype storage uses contiguous component arrays per chunk.
  • Chunk memory is fixed-size (Chunk.CHUNK_BUFFER_SIZE) to bound allocations and improve locality.
  • Component layouts are precomputed per archetype:
    • offset,
    • size,
    • enable-bit offset,
    • version index.

Why it matters:

  • Sequential memory access in inner loops.
  • Fewer pointer indirections than object-per-entity layouts.

Structural Cost Model

Structural changes are intentionally explicit and potentially expensive.

  • AddComponent / RemoveComponent move entities between archetypes.
  • Removal uses swap-back compaction to keep chunks dense.
  • Batch destroy path sorts locations and processes by chunk to reduce random work.

Guidance:

  • Prefer bulk creation APIs (CreateEntities) over repeated single inserts.
  • Minimize structural churn in hot update loops.
  • Use EntityCommandBuffer to defer structural edits.

Query Efficiency

  • Queries are compiled into bitset masks.
  • Query instances are cached by mask hash in ComponentManager.
  • New archetypes are incrementally tested and added to existing query match lists.

Guidance:

  • Build query once, reuse query ID.
  • Avoid rebuilding identical queries every frame.

Enableable Components

Enableable state is stored in bitmasks per chunk.

  • Toggle with EntityManager.SetEnabled<T>(...).
  • Query semantics (WithAll, WithNone, WithDisabled, WithPresent) combine structural and enablement checks.

Guidance:

  • Prefer enable/disable for state toggles over add/remove where possible.

Change Versioning

The runtime tracks:

  • world version (World.Version),
  • chunk structural version,
  • per-component version per chunk.

ChunkView APIs such as HasChanged<T>(version) allow change-filtered work.

Guidance:

  • Cache last processed version per system/subsystem.
  • Skip unchanged chunks/components when possible.

Jobs and Parallel Chunk Processing

EntityQuery.ScheduleChunkParallel transforms matched chunks into job batches and schedules IJobParallelFor work.

Guidance:

  • Use chunk jobs for broad data transforms.
  • Keep batchSize tuned for your workload.
  • Chain dependencies correctly and wait only at necessary sync points.

Allocation and Lifetime Hygiene

  • Temporary data often uses stack/temporary allocators (AllocationManager.CreateStackScope).
  • Persistent containers are explicitly disposed.

Guidance:

  • Keep temporary allocations scoped and short-lived.
  • Always dispose worlds, schedulers, and persistent collections deterministically.