Search Unity

Question Multiple Dynamic Buffers vs One Dynamic Buffer with IDs

Discussion in 'Entity Component System' started by toomasio, Apr 21, 2021.

  1. toomasio

    toomasio

    Joined:
    Nov 19, 2013
    Posts:
    199
    Hello,

    So I have ran into a situation where I am going to be using the same struct data types for multiple uses.

    for example (multiple buffers):
    the data:
    Code (CSharp):
    1. public struct PhysicsHitData : IEquatable<PhysicsHitData>
    2.     {
    3.         public ColliderKey colliderKey;
    4.         public Entity entity;
    5.         public float fraction;
    6.         public float3 position;
    7.         public int rigidBodyIndex;
    8.         public float3 surfaceNormal;
    9.  
    10.         public bool Equals(PhysicsHitData other)
    11.         {
    12.             return colliderKey.Equals(other.colliderKey)
    13.                 && entity.Equals(other.entity)
    14.                 && fraction.Equals(other.fraction)
    15.                 && position.Equals(other.position)
    16.                 && rigidBodyIndex.Equals(other.rigidBodyIndex)
    17.                 && surfaceNormal.Equals(other.surfaceNormal);
    18.         }
    19.     }
    the buffers:
    Code (CSharp):
    1. public struct PhysicsTriggerStayBuffer : IBufferElementData, IBufferContainer<PhysicsHitData>
    2.     {
    3.         public PhysicsHitData hitData;
    4.         public PhysicsHitData BufferContainerData { get => hitData; set => hitData = value; }
    5.     }
    Code (CSharp):
    1. public struct PhysicsTriggerEnterBuffer : IBufferElementData, IBufferContainer<PhysicsHitData>
    2.     {
    3.         public PhysicsHitData hitData;
    4.         public PhysicsHitData BufferContainerData { get => hitData; set => hitData = value; }
    5.     }
    Versus using a "name" for the ID instead...having the systems only apply logic to those IDs:

    Code (CSharp):
    1. public struct PhysicsHitBuffer : IBufferElementData, IEquatable<PhysicsHitBuffer>, IBufferContainer<PhysicsHitData>
    2.     {
    3.         public FixedString64 name;
    4.         public PhysicsPositionData positionData;
    5.         public PhysicsHitData hitData;
    6.         public PhysicsDebugData debugData;
    7.  
    8.         public PhysicsHitData BufferContainerData { get => hitData; set => hitData = value; }
    9.  
    10.         public bool Equals(PhysicsHitBuffer other)
    11.         {
    12.             return name.Equals(other.name)
    13.                 && positionData.Equals(other.positionData)
    14.                 && hitData.Equals(other.hitData)
    15.                 && debugData.Equals(other.debugData);
    16.         }
    17.     }
    What is faster? Having multiple buffers with the same kind of data or have all my data route through one buffer with IDs?

    I am trying to make my workflow as efficient as possible but I also worry about performance down the line, since I will be using this type of data quite a bit.

    Any help is appreciated! Thanks,
     
  2. PublicEnumE

    PublicEnumE

    Joined:
    Feb 3, 2019
    Posts:
    729
    Hi!

    The answer will depend on what you’re doing with them. If your logic always involves iterating over everything that would exist in all three buffers, then having everything in a single buffer will be faster. But if your logic only needs to iterate over one buffer’s worth of entries at a time, then keeping separate buffers might be marginally faster...or at least more efficient. You’ll be loading a buffer that contains only the data you need for your current purpose.

    But in terms of good organization, it sounds like keeping separate buffers is probably the better approach in your case. You might consider doing this:

    1. Create three different structs, with three different names, which just happen to contain the same data. Name each one to match the way it will be used.

    2. Create three separate buffers to store the data.

    The three structs may have the same data layout, but because they represent different things, it’s ok to consider them as being different types.

    a real world example: a form with identical fields might be used by both a doctor’s office and the military, but they could still be considered different forms - separated by their different uses.

    That’s the approach I would suggest. GL!
     
    toomasio likes this.
  3. tzxbbo

    tzxbbo

    Joined:
    Dec 14, 2019
    Posts:
    100
    Hi, I'm wondering with the id approach, Do we still need a dynamic buffer, why not just spawn data entities and query them isn't this even faster as we don't have the overhead caused by the buffer?