I’m building a new entity system in Java. I’m wondering whether my proposed method would cause any issues, architecture-wise or performance-wise.
I want:
...
for (Entity entity : entities)
{
for (Entry<String, Component> entry : entity.components.entrySet()) //collection is a Map
{
Component component = entry.getValue();
component.update(deltaTime);
}
}
...
vs. the undesirable alternative:
...
for (Entity entity : entities)
{
if (entity.componentA != null)
entity.componentA.update(deltaTime);
if (entity.componentB != null)
entity.componentB.update(deltaTime);
//etc. for as many components as the entity has. Finite, but possibly many.
}
...
With the first approach, some things I’ve thought of in regard to the HashMap approach:
- I would avoid unecessary conditionals (non-trivial when thousands of entities are having their
update()called); - Read access time is O(1) on average (the only time you’re likely to not get that is on a hash collision);
HashMap.entrySet()must be called to iterate over the collection using for-each syntax. As I understand it from the docs, “the collection [set] is backed by the map”. However this does not tell me if HashMap is internally creating the set, each timeentrySet()is called.
The first version is almost certainly going to be the best design:
If you really care about performance and have already profiled that this is an important special case, you may want to consider writing a custom data structure (e.g.
ComponentList) for entity.components, which would have an additional methodsupdateAll(deltaTime)to efficiently perform the update operation for all contained components. This has a couple of advantages: