Search Unity

Unity ECS perfomance is worst than in third-party ECS?

Discussion in 'Entity Component System' started by Sergey_Suslov, Apr 2, 2018.

  1. Sergey_Suslov

    Sergey_Suslov

    Joined:
    Nov 20, 2017
    Posts:
    12
    Or maybe im doing something wrong? ;)

    Samsung j1 mini.
    10000 entities, single thread.

    Unity ECS - 40fps
    Unity-Ash ECS - 50fps

    Both systems just increments int variable.

    Unity ECS:
    Code (CSharp):
    1.     protected override void OnUpdate()
    2.     {
    3.         var i = 0;
    4.  
    5.         foreach (var e in GetEntities<TestNode>())
    6.         {
    7.             i++;
    8.         }
    9.     }
    Ash:
    Code (CSharp):
    1. public void Update(float deltaTime)
    2.     {
    3.         int i = 0;
    4.         foreach (TestNode node in _nodes)
    5.         {
    6.             i++;
    7.         }
    8.     }
    Test source in attachments:
     

    Attached Files:

    Last edited: Apr 2, 2018
  2. Sergey_Suslov

    Sergey_Suslov

    Joined:
    Nov 20, 2017
    Posts:
    12
    Well, time of adding/removing entities is more important than iteration time, so i will test it tomorrow.
     
  3. recursive

    recursive

    Joined:
    Jul 12, 2012
    Posts:
    669
    I've heard in other threads that using Group injection is more performant than GetEntities<>().

    Try something like this:

    Code (CSharp):
    1.  
    2.  
    3. struct TestNodeGroup
    4. {
    5.         public ComponentDataArray<TestNode> TestNodes;
    6.         public int Length;
    7. }
    8.  
    9. [Inject] TestNodeGroup _testNodeGroup;
    10.  
    11. protected override void OnUpdate()
    12. {
    13.         var i = 0;
    14.         var len = _testNodeGroup.Length;
    15.         for(; i < len; ++i)
    16.         {
    17.                 ++i;
    18.         }
    19. }
    20.  
    21.  
    In addition, add/removing components frequently could cause issues as the entity will need to be migrated to a new archetype (set of related components that determine how/where the entity is allocated). There are ways of batching these changes for performance.
     
  4. Sergey_Suslov

    Sergey_Suslov

    Joined:
    Nov 20, 2017
    Posts:
    12
    ComponentDataArray is only working with IComponentData, which is not usable with classic gameobjects, prefabs etc :(
     
  5. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    300
    fps isn't a very specific measurement, try using a profiler and check milliseconds used for certain operations to find out what is going on.
     
  6. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    We provide main thread access for simplicity / integration with existing main thread only Components etc.

    If you want to get performance, please look at using IComponentData + JobComponentSystem + Burst. This is where you will see roughly 100x speedups.

    Additionally please make sure to profile in standalone player, in editor there is additional checks that are stripped out at deployment.

    That said there looks to be some low-hanging fruits for optimizing the access of foreach iteration
     
    Last edited: Apr 3, 2018
    RaL likes this.
  7. Spy-Shifty

    Spy-Shifty

    Joined:
    May 5, 2011
    Posts:
    546
    You can use IComponentData for classic GameObjects! Just use the ComponentDataWrapper and Serialization!

    Code (CSharp):
    1. [Serialization]
    2. struct Health : IComponentData {
    3.     public float Value;
    4. }
    5.  
    6. public class HealthComponent : ComponentDataWrapper<Health> { }
    Add HealthComponent to your GameObject.

    You can also instantiate your Prefab and add all components by script. Your Perfab also requires a GameObjectEntity component.

    IComponentData can than be computed with Jobs. Only legacy components like Animator, Rigidbody, Collider,... can't be computed in parallel.