A suite of benchmarks designed to test and compare JavaScript ECS library performance across a variety of challenging circumstances.
SoA implementations
| op/s | packed_5 | simple_iter | frag_iter | entity_cycle | add_remove |
|---|---|---|---|---|---|
| bitecs | 335,064 | 115,954 | 431,207 | 1,634 | 2,334 |
| harmony-ecs | 313,278 | 132,026 | 489,903 | 4,040 | 4,194 |
| piecs | 364,652 | 177,269 | 470,904 | 64,075 | 20,649 |
| wolf-ecs | 378,471 | 165,951 | 535,362 | 2,597 | 3,913 |
Object-based implementations
| op/s | packed_5 | simple_iter | frag_iter | entity_cycle | add_remove |
|---|---|---|---|---|---|
| becsy | 103,417 | 28,337 | 61,296 | 692 | 8,953 |
| ecsy | 7,822 | 4,822 | 24,537 | 120 | 975 |
| geotic | 45,957 | 29,631 | 49,482 | 106 | 1,099 |
| goodluck | 53,927 | 31,894 | 77,575 | 27,253 | 301,727 |
| javelin-ecs | 65,990 | 38,474 | 121,207 | 656 | 3,286 |
| miniplex | 109,296 | 36,316 | 20,372 | 310 | 6,645 |
| perform-ecs | 55,241 | 94,791 | 31,170 | 159 | 442 |
| picoes | 6,814 | 4,223 | 12,368 | 2,679 | 4,303 |
| tiny-ecs | 16,391 | 35,488 | 45,760 | 194 | 1,082 |
| uecs | 29,855 | 14,747 | 9,861 | 1,724 | 5,207 |
The best result for each benchmark is marked in bold text. Note that run to run variance for these benchmarks is typically 1-4%. Any benchmarks within a few percent of each other should be considered “effectively equal”. The above benchmarks are run on node v17.8.0.
@javelin/ecs@lastolivegames/becsybitecsecsyharmony-ecsgeoticgoodluckminiplexperform-ecspicoespiecstiny-ecsuecswolf-ecs
This benchmark is designed to test the core overheads involved in component iteration when multiple queries are run.
- Dataset: 1,000 entities, each with
(A, B, C, D, E)components. - Test:
- Iterate through all entities with
Aand double its value. - Iterate through all entities with
Band double its value. - Iterate through all entities with
Cand double its value. - Iterate through all entities with
Dand double its value. - Iterate through all entities with
Eand double its value.
- Iterate through all entities with
This benchmark is designed to test how efficiently the ECS can run multiple independent systems.
- Dataset:
- 1,000 entities with
(A, B)components - 1,000 entities with
(A, B, C)components - 1,000 entities with
(A, B, C, D)components - 1,000 entities with
(A, B, C, E)components
- 1,000 entities with
- Test: Three systems accessing the following components, where each system swaps the values stored in each component:
(A, B)(C, D)(C, E)
This benchmark is designed to test how the ECS handles iteration through a fragmented dataset.
- Dataset: 26 component types (
AthroughZ), each with 100 entities plus aDatacomponent. - Test:
- Iterate through all entities with a
Datacomponent and double its value. - Iterate through all entities with a
Zcomponent and double its value.
- Iterate through all entities with a
This benchmark is designed to test the base cost of constructing and destroying entities into the ECS.
- Dataset: 1,000 entities with a single
Acomponent. - Test: Iterate through all entities, and create 1 entity with a
Bcomponent. Then iterate through all entities with aBcomponent and destroy them.
This benchmark is designed to test how quickly the ECS can add and then remove a component from an existing entity.
- Dataset: 1,000 entities with a single
Acomponent. - Test: Iterate through all entities, adding a
Bcomponent. Then iterate through all entities again, removing theirBcomponent.