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_indexfor table-backed componentsall_indexfor table + sparse lookups
That changes the expected behavior of the common query paths:
get_table_entities_with_component()uses the direct table indexget_all_entities_with_component()uses the all-storage indexSimpleQueryselects 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
ArchetypeWorldoutperformSimpleWorld - 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
SimpleWorldvsArchetypeWorldmulti-component query comparisonSimpleWorldvsArchetypeWorldstructural mutation comparison
Reading The Current Benchmarks
Interpret the benchmark output in this order:
Query PathsIf plain indexed queries and cached queries are already cheap enough, stay onSimpleWorld.Backend Query ComparisonIfArchetypeWorldis materially better on your real multi-component query shape, it may be worth adopting.Backend Structural Mutation ComparisonIf archetype migration is significantly more expensive for your workload, do not switch just because query numbers look better in isolation.Query Cache InvalidationIf 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.