Performance tweaks of reactive systems in Entity Component System

Reactive systems in ECS can be very useful for processing custom reaction on component changes. But how we can be sure that filtered entities will be processed once and without performance penalties?

Reactive systems in ECS can be very useful for processing custom reaction on component changes. But how we can be sure that filtered entities will be processed once and without performance penalties?

So, standard behaviour during adding new entity to React-system filtered collection - check if new entity already exists in this collection, sounds easy. Type of this collection is List<int>, it means that we can use something like this:

1
2
3
4
5
6
void AddNewEntity (int entity) {
if (_entities.IndexOf(entity) == -1) {
// new entity, we can add it
_entities.Add(entity);
}
}

Looks good, but works very slow on thousands of entities. What about using some hash-collections like HashSet or Dictionary?

1
2
3
4
5
6
7
8
// HashSet<int>
void AddNewEntity (int entity) {
if (!_entityHashes.Contains(entity)) {
// new entity, we can add it
_entityHashes.Add(entity);
_entities.Add(entity);
}
}

1
2
3
4
5
6
7
8
// Dictionary<int, bool>
void AddNewEntity (int entity) {
if (!_entityHashes.ContainsKey(entity)) {
// new entity, we can add it
_entityHashes[entity] = true;
_entities.Add(entity);
}
}

It works much faster, but eats more memory (but we cant drop basic List<int> collection - it will be used later). Strange, but Dictionary works faster than HashSet, maybe its issue of Unity mono framework.
So, how we can increase performance more? We can write custom hashset based on standard Dictionary, removing all useless parts and make tweaks special for out case (int-based data).

Final implementation of custom HashSet was created to increase performance of data processing in ECS framework: it works faster than standard hash collections, eats less memory and already tweaked for inlining with mono4.6. Overall performance of UpdateComponent / React-system with OnUpdate behaviour was increased in 15%, ECS framework now processing filtered entities with React-systems in same speed as Entitas, but without codegen.