ECS in Rust
Table of Contents
Introduction⌗
Since I’ve already described ECS before on my previous post, I won’t be explaining it here. If you want to learn more about that, you can do so here: Learning about ECS. Basically it is a way to structure your code by using entities, components, and systems.
ECS is used a lot more in Rust game development rather than anywhere else and the cause of that may be because Rust really likes the composition over inheritance principle, like for example, using traits rather than inheritance.
There is a lot of ECS libraries for Rust and in this post, we will be benchmarking a couple of ECS libraries that I found interesting.
Libraries we will be covering⌗
Libraries we will be covering for this post are:
There are still a lot more ECS libraries for Rust, but these are the ones that I found interesting for some kind of reason.
Note: Bevy ECS is actually a part of another library called Bevy which is a full game framework
Benchmarks⌗
The benchmarks for the libraries are gonna be:
unbatched_spawn
: Spawnn
amount of entities by spawning them one by one.batched_spawn
: Spawnn
amount of entities batchedadd_remove
: Add a component ton
amount of entities and then remove the componentiter
: Iterate overn
amount of entitiesmultiple_iter
: Iterate overn
amount of entities with different components parallellymultiple_iter_same
: Iterate overn
amount of entities with the same components parallellyiter_mut
: Iterate mutably overn
amount of entitiesmultiple_iter_mut
: Iterate mutably overn
amount of entities with different components parallellymultiple_iter_mut_same
: Iterate mutably overn
amount of entities with the same components parallelly
In the project page, n
is three values: 1,000, 100,000, and 1,000,000. For this post, we’re gonna cover only the last part. Be sure to check out the full project.
Results⌗
The full project is at https://github.com/ManicMarrc/ecs_benchmark/tree/main.
unbatched_spawn
⌗
As you can see from the graph, edict is the slowest of them and hecs being the fastest one. This is the only one time where Edict is slow as you’ll see for the next few benchmarks.
batched_spawn
⌗
You may have noticed that Edict isn’t anywhere in this graph. That’s because it is way faster than the others, so fast in fact, it’s not even visible on the graph as the others are too slow!
add_remove
⌗
Again in this graph, Edict is not visible at all. Bevy ECS being the slowest one out of all of them and Shipyard being the second fastest.
iter
⌗
Are you seeing a pattern here? Cause I am. Basically the same as the add_remove
benchmark with Bevy ECS being the slowest one.
multiple_iter
⌗
Edict is actually visible on this graph being only one pixel. Again, the same pattern as the aforementioned benchmarks.
multiple_iter_same
⌗
The pattern still repeats for this one.
iter_mut
⌗
This one is actually interesting. While Edict and Bevy ECS stays the same in their position, Shipyard and Hecs are fighting to be in the second position. Shipyard averagely performs better than Hecs, but sometimes, Hecs performs better than Shipyard.
multiple_iter_mut
⌗
This one follows the original pattern, nothing interesting.
multiple_iter_mut_same
⌗
For this one, Hecs gets kinda close to Shipyard but is still a little bit slower than it.
Summary⌗
Although Edict was the slowest one by far for the unbatched_spawn
benchmark, it passed every other libraries in the other benchmarks.
Bevy ECS was by far the slowest one of them all, being last in every single benchmark except for the unbatched_spawn
benchmark.
Hecs and Shipyard have close speed, with Shipyard being faster in most cases.
Ending Off⌗
Note that these benchmarks are ran on my super old computer which may affect the benchmark results. You can benchmark them yourself easily by just cloning the Github page and running cargo bench
and wait a while.
That’s all for this post, see you and goodbye!