Cougr Performance Guide

Purpose

This document explains the current performance model for Cougr's Soroban-first ECS path.

It is not a promise of fixed gas costs. It is a guide to the data structures and tradeoffs that determine query and scheduling behavior.

The practical question it should answer is:

  • which backend should I use
  • where should a component live
  • what kinds of mutations are cheap versus expensive

SimpleWorld Query Model

SimpleWorld now maintains direct component indexes:

  • table_index for table-backed components
  • all_index for table + sparse lookups

That changes the expected behavior of the common query paths:

  • get_table_entities_with_component() uses the direct table index
  • get_all_entities_with_component() uses the all-storage index
  • SimpleQuery selects the narrowest available required component index before filtering

This is the default performance story for gameplay loops.

Use SimpleWorld by default when:

  • your hot loop is dominated by one- or two-component scans
  • you mutate entity composition often
  • you rely on table vs sparse placement to control scan scope

Use ArchetypeWorld when:

  • your hot loop is dominated by repeated multi-component queries
  • entity compositions are relatively stable after setup
  • you are willing to pay more for add/remove migrations to get tighter query scopes

Storage Tradeoffs

Table storage:

  • optimized for repeated scans
  • should back components that appear in hot gameplay loops

Sparse storage:

  • better for infrequent markers or tags
  • excluded from table-only scans by default

If a sparse component starts showing up in tick-critical queries, it is usually a signal that the component belongs in table storage.

Prescriptive rule:

  • if you scan it every tick, it probably belongs in table storage
  • if you mostly address it directly or use it as a sparse marker, keep it sparse

Scheduler Tradeoffs

SimpleScheduler now validates stage-local dependencies before execution.

Costs introduced by the stronger model:

  • dependency validation during run planning
  • topological ordering within each stage

Benefits:

  • explicit execution order
  • early detection of invalid schedules
  • safer composition as system counts grow

This is a good trade in Soroban-oriented contracts because schedule size is typically small relative to the cost of incorrect execution order.

Benchmark Focus Areas

Benchmarks should answer these practical questions:

  • how many entities can the indexed query path scan efficiently
  • when does ArchetypeWorld outperform SimpleWorld
  • what is the cost of adding/removing indexed components
  • what is the cost of stage validation and deferred command application

The current benchmark suite in benches/ecs_bench.rs covers these paths directly.

It now includes:

  • entity spawn cost
  • component insert / lookup cost
  • indexed query vs sparse-inclusive query cost
  • cache warm-read vs invalidated-read behavior
  • scheduler validation + execution cost
  • SimpleWorld vs ArchetypeWorld multi-component query comparison
  • SimpleWorld vs ArchetypeWorld structural mutation comparison

Reading The Current Benchmarks

Interpret the benchmark output in this order:

  1. Query Paths If plain indexed queries and cached queries are already cheap enough, stay on SimpleWorld.
  2. Backend Query Comparison If ArchetypeWorld is materially better on your real multi-component query shape, it may be worth adopting.
  3. Backend Structural Mutation Comparison If archetype migration is significantly more expensive for your workload, do not switch just because query numbers look better in isolation.
  4. Query Cache Invalidation If your world mutates every tick, cache benefits may collapse; optimize data shape first.

Decision Heuristics

Choose SimpleWorld when:

  • gameplay writes are frequent
  • entity compositions change often
  • table/sparse separation gives you enough control
  • your queries are broad but predictable

Choose ArchetypeWorld when:

  • the same multi-component query runs constantly
  • compositions are mostly fixed after startup
  • entity migration cost is amortized over many reads

Keep GameApp, SimpleWorld, and SimpleQuery as the default performance story for new Soroban gameplay code.

Interpretation Rules

Use benchmark output to compare patterns, not to claim universal throughput numbers.

For real contracts, evaluate:

  • data shape
  • component cardinality
  • table vs sparse placement
  • how often the world mutates between repeated queries

Performance guidance should always be tied back to those conditions.

If benchmark results and your data shape disagree, trust the data shape first.