Search Unity

Performance degradation over time due to ever increasing Archetype count

Discussion in 'Entity Component System' started by MartijnGG, Oct 10, 2018.

  1. MartijnGG

    MartijnGG

    Joined:
    May 3, 2018
    Posts:
    74
    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?
     
    5argon and oliverbalaam like this.
  2. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    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.
     
    FROS7 likes this.
  3. MartijnGG

    MartijnGG

    Joined:
    May 3, 2018
    Posts:
    74
    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.
     
  4. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    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.
     
    timmehhhhhhh and FROS7 like this.
  5. MartijnGG

    MartijnGG

    Joined:
    May 3, 2018
    Posts:
    74
    Is the suggested solution for now to use a ComponentGroup, and then create the ArchetypeChunk array from this?
     
  6. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    IJobProcessComponentData for the majority of all jobs and ArchetypeChunk via ComponentGroup where necessary.
     
  7. capyvara

    capyvara

    Joined:
    Mar 11, 2010
    Posts:
    80
    Omg there's ArchetypeChunks in ComponentGroup, also a IJobChunk, for some reason I've missed that.

    Can I assume IJobChunk is recommended too?
     
  8. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    yes
     
    T-Zee likes this.
  9. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    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<T>) 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<T>(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` ?
     
    Last edited: Oct 11, 2018
  10. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    FYI (if I understand you - ACCT is GetArchetypeChunkComponentType and you must not use it from EntityManager)
    upload_2018-10-11_8-12-26.png

    Edit: Oh i think you mean ACA with EntityManager, damn language barrier :) Thus ignore my message :)
     
    The5 likes this.