ComponentLookup vs GetComponent

Hi! I don’t quite understand how a componentLookup works and have a few question.

  1. From this documentation, I know that it is a stand-alone native container, which stores RAM pointers to component data in chunks and maps them to entities. Am I right?
  2. if I want to iterate archetype A and access components from other archetypes using foreach(var xx in SystemAPI.Query()), which is proper to use, ComponentLookup or systemAPI.GetComponent
  3. when I use ComponentLookup in ISystem, should I GetComponentLookup at OnCreate and update it each time I use it? Or just getComponentLookup as a local variable in the OnUpdate method?
  1. You can get the ComputeLookup at OnCreate() but make sure to call ComputeLookup.Update() in OnUpdate().

I don’t use SystemAPI so I’m not sure what to answer about 2.

1 Like
  1. it’s an accessor for shared data structures for the world, not something that stores data on its own
  2. Docs say SystemAPI uses ComponentLookup for that so there’s no significant difference
  3. prefer to create and update, as the update is pretty simple and you usually want to the least amount necessary for repetitive tasks
2 Likes
  1. ComponentLookup is a very lightweight struct with some cached fields for faster lookups. All it does is probe into the EntityDataAccess and resolves an Entity to get the chunk it resides in and the index. So in other words, efficiently get the memory address where the actual component data is. Then it’s just a matter or dereferencing the pointer data and returning it to you. If you use the normal accessor lookup[entity] it will return T and a copy of the data. (slower)
void* ptr = ecs->GetComponentDataWithTypeRO(entity, m_TypeIndex, ref m_Cache);
UnsafeUtility.CopyPtrToStructure(ptr, out T data); // this returns the copy

Instead you want to get the data by reference and that’s what the GetRef methods are for.

  1. ComponentLookup is fine. Although I’ve seen this quite a few times now, nested SytemAPI.Query usage and all I can say is, don’t! Instead use something like .ToEntityArray or .ToComponentDataArray (name could differ) and prepare the data so you can process it in one loop and even better, job.

  2. SystemAPI.GetComponent and as with any SystemAPI uses code generation. So behind the scenes it will create a ComponentLookup field, the appropriate call in OnCreate and in Update. So you want to use the SystemAPI version as it’s only 1 line :slight_smile:

1 Like

Hi, Enzi. Thanks for the reply!
By the way, I wonder if it’s better to use .ToComponentArray before the iteration than use .getComponentRO in a SystemAPI.query if I know that most of the data in the array will be read during the iteration because that condenses the data for a higher cache hit rate. Does it make any sense?