Performance degradation over time due to ever increasing Archetype count

I’m been seeing some rather painful performance issues in my project which is dynamically adding and removing a good amount of ComponentType’s to my entities.

I’ve found that due to the nature of how this is done dynamically, ECS will keep making an archetype whenever it encounters a unique combination of types after I add a new component to an entity, which will then be added to the linked list of existing archetypes.

However if I later remove this component, leaving the archetype with 0 entities, it will never be cleaned up.
This causes the list of archetypes to keep growing and growing until contains every single possible combination of dynamic components I’ve been adding and removing.

The performance issue comes from the multiple places where ECS will iterate over this entire list.
This iteration is currently done for ComponentGroups and Archetype queries, becoming heavier the longer my game runs.

Is there a way to have it periodically clean up Archetypes that haven’t had an entity for a while? Or have the Archetypes stored in a different way, so that full traversal of the linked list is not required?

2 Likes

Archetype queries become heavier. ComponentGroups should not. Archetype can now be done through ComponentGroup instead of from scratch… In the future we will only allow querying through the ComponentGroup API for this reason.

1 Like

I only use Archetype queries in a single place, but have been seeing the decrease in performance with ComponentGroups as well. The issue is caused within the ComponentChunkIterator.MoveToEntityIndex in the ComponentDataArray’s

I’ll provided a minimum example project this week.

We are aware of exactly that, and have a plan to improve it. Part of it is removing ComponentDataArray.

IJobProcessComponentData + ArchetypeChunk don’t stuffer from same issues.

2 Likes

Is the suggested solution for now to use a ComponentGroup, and then create the ArchetypeChunk array from this?

IJobProcessComponentData for the majority of all jobs and ArchetypeChunk via ComponentGroup where necessary.

4 Likes

Omg there’s ArchetypeChunks in ComponentGroup, also a IJobChunk, for some reason I’ve missed that.

Can I assume IJobChunk is recommended too?

yes

1 Like

I have some question in doing work with ComponentGroup without ComponentDataArray.

On creating the ComponentGroup we must specify types, along with it is read-only status. (ComponentType.ReadOnly/Create) Then to iterate through data the recommended way is to cg.CreateArchetypeChunkArray. But also there is EntityManager.CreateArchetypeChunkArray.

To use ACA, I have to input result from system’s GetArchetypeChunkComponentType(readOnly); which again contains read only status. When using ACCT with EntityManager-made ACA it should follow access modifier that you specify later on ACCT, but what about using it with ComponentGroup-made ACA? Can I switch between read only/RW freely regardless of the read status I provided at the creation of ComponentGroup in OnCreateManager?

Also where in the chunk iteration method that it trigger the “changed” status of the chunk? Currently the to be depricated ComponentDataArray seems to update the version on write. If I used chunk iteration everywhere already when will I detect archetypeChunk.DidChange ?

FYI (if I understand you - ACCT is GetArchetypeChunkComponentType and you must not use it from EntityManager)
3772930--315214--upload_2018-10-11_8-12-26.png

Edit: Oh i think you mean ACA with EntityManager, damn language barrier :slight_smile: Thus ignore my message :slight_smile:

1 Like