Are HashMaps bad for Entity-Component-System Architectures?

My ECS uses HashMaps to represent Components and their features, and each Entity has a HashMap that contains components. Every time a component is added, it generates a String tag that is attached to the Entity, which each System checks for to make sure the component actually exists for said Entity.

I was reading up the Artemis info and they say that HashMaps are bad data structure. Is it? Since my design uses a HashMap container to store multiple HashMaps, is there a more efficient way that I should be doing this, or should I only worry about it if performance is a big problem?

From my experience (I might be 100% wrong) hashmaps is like the slowest storing method. Fastest is an array, then come lists, and after that the hashmap.

ah :frowning: Would it be possible to create an enum to represent a global index that I can use to refer to components and their parts? The main reason I used HashMap was because of the ease-of-use of the Key-Value system

Is there a limit on the number of components a container can hold?

You can just write a getter method for ease of use.

Most ECS frameworks have some sort of array-like data structure per component type. In artemis each entity is given an integer id: the id represents the index at which the component is stored.

Unless you have a lot of entities, you probably won’t see a noticeable performance hit (ofc depends on platoform, entity count, GC and so forth). One of the ideas behind ECS, besides reducing complexity as the project grows, is performance: if all instances of ComonentX are aligned in memory, you’ll get faster memory access (better cache locality), but java doesn’t easily lend itself to contiguous memory layout when it comes to objects.

edit: If entities hold on to their own components, how do you get all entities matching a specific component composition?
edit 2: If you want to stick with your current approach - consider using the component’s class as key and replacing the HashMap with IdentityHashMap - getClass() always returns the same object per class.

HashMaps can be very fast. In many cases as fast as and array. The random access can hurt somethings. But mostly don’t worry about. If you don’t have some profiling results showing that your maps are your problem, don’t don’t optimize it. And if it did become a problem there are a number of alternatives from java.util. that can just be dropped in.

If you want key value lookup. Just use a hash table.

Don’t forget the TreeMap… should give slower insert and faster read.

In my ECs I just put everything in a list and iterate. I have specific methods to get at the commonly used properties.

Each entity has a tag container. Each system checks if the Entity has the required tags, then performs the methods on the components that exist.

No. But there are different variants of components, and the entity can only have one type of variant

I have a fetch method that I use to pull data from the components of a specific entity. When I looked at it recently I thought it would work just as fine if I used an Object[] instead of HashMaps

I know it can never be said enough, and will never be said enough, but:

Don’t optimize until you need to optimize.
How do you know you need to optimize?
The profiler will tell you.

Chances are a HashMap is plenty fast. And if it’s not, then the first thing you should do is try not using Strings, but Integers instead or something. (compare String.hashCode() vs. Integer.hashCode())

And if it’s still not good enough, the HPPC library should have you covered for speed while still letting you use your nice Maps.

So it “component by (variant) type” instead of straight type or name? If so then obviously there can only be a finite number of variants. What’s your projected upper limit?

Well not every component has a variant. The only components that currently have variants are the Renderer and Logical components, since different entities could use different rendering methods, or have different logical steps. But there is no real limit to all of the other components.

Then you’re stuck with hashing.

(EDIT: well assuming that the lookup probabilities are roughly equal per contained type)