Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Split logic into different systems vs ComponentDataFromEntity

Discussion in 'Entity Component System' started by Adrian-Anta, Mar 10, 2020.

  1. Adrian-Anta

    Adrian-Anta

    Joined:
    Oct 26, 2012
    Posts:
    33
    I'm working on a IJobForEachWithEntity that calculates the cost for all items in a store every frame. There are a million items, just to test the performance impact of the different solutions I'm implementing.

    Each item has a different amount of components attached, but all the system cares about is that they are all items.

    Depending on which components the item have I'd like to increase the total cost. For example, if there's a component labelled as Premium then the cost will increase by an X amount. This is a silly example, but I'm just using this to learn.

    The thing is that if I just look for all items and then within the system I call ComponentDataFromEntity.Exists + componentDataFromEntity[entity] to check if there's a premium component attached to the item and then access to it, the performance drops really hard.
    But if I create a second system that goes after the first and checks for the archetypes item and premium, and it does the same operation it goes much smoother.

    To give context it goes from 350 fps to 80 fps. I'm using Burst in both examples.

    This makes kind of sense, because of the random memory access of ComponentDataFromEntity, but it's counter-intuitive in the way that I have to duplicate a lot of code to get very simple operations done faster.

    I'm wondering if I'm missing something really obvious or this is indeed the way to go. I've read many posts from Joachin Ante himself saying that ComponentDataFromEntity is pretty efficient. So before going any further, I'd like to ask.

    Thanks.
     
  2. brunocoimbra

    brunocoimbra

    Joined:
    Sep 2, 2015
    Posts:
    677
    Did you made both tests in a build? The results may be surprisingly different inside the Editor.
     
  3. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,627
    ComponentDataFromEntity is pretty efficient but it isn't the most efficient way (as you say the random access.)

    Have you considered just attaching the Premium component to all items with a bool field?
     
  4. Adrian-Anta

    Adrian-Anta

    Joined:
    Oct 26, 2012
    Posts:
    33
    So I made a couple of builds with 10 million items and I get:

    7.5 ms (2 concatenated systems [UpdateAfter])
    23 ms (Getting the premium component with ComponentDataFromEntity)

    I assume this example is badly designed and there's no way it can get better performance without refactoring how the data is stored.

    As you mentioned by adding a field to the Premium component I could also avoid using ComponentDataFromEntity and it would be also faster I assume. It's a good solution to the problem.

    Is there a relationship between the number of components attached to an entity and the app's performance?

    Maybe there's this huge gap between solutions because the number of iterations involved? For smaller-scale examples using one solution vs the other won't be noticeable I guess.