Are associative arrays a good idea for games? Perhaps, depending on your needs.
However, you need to differentiate between comments about "associative arrays" and specifically about the class std::map
.
Associative Arrays
Associative arrays are just some kind of data structure that allows you to associate one kind of value with another, such that you can look up a value with another value. There are many kinds of associative arrays, some of which are really implemented with a regular array.
Hash tables are a form of associative array.
The "conventional wisdom" among many C-style game developers is that looking up entities by name is not worth it. This "wisdom" effectively says that your entities should be in one big global fixed-size array. When you create a new one, you find an unused index, set it to be used, and you pass the "index" around as the name.
Entities may have an actual string name, but you won't be using that to find the entity by name very often; generally speaking, you will reference entities by either pointer or index. This is still an associative array; it just uses an index rather than a name as its key value.
One pitfall you may have with associative arrays is that you may need to collate entities based on different properties. Things like "find all entities with blue hands" or whatever. Your associative array isn't going to help you; you'll have to take a linear walk down the entire list of entities to deal with that.
If your game does this kind of collation a lot, then adding other data structures might be a better way to go. Of course, that's rather complex.
std::map
std::map
is a specific implementation of an associative array. And while it is the shortest associative array in the standard library, it has certain performance quirks.
Specifically, every insertion is a memory allocation. But more than that, because the memory is likely not contiguous, accessing different elements will likely miss the cache. If you ever need to walk through the list of all entities (to render them, update their position, etc), every entity is basically going to be a full cache miss.
You can read more in this PDF; it talks about std::set
, but they're both the same under the hood.
The "conventional wisdom" I stated earlier tends to avoid that issue. But really, it's bad coding for C++. It's really just a poorly-designed pool allocator, and an actual pool allocation system would be far better at achieving the same effect.
A better alternative would be using Boost.Container's flat_map
class. It essentially takes the concept of a sorted vector
from the PDF and implements a variation of set
and map
from it. Insertion and deletion will be slightly painful, as it will have to shuffle elements around. They'll be more painful than the pool allocator case, certainly. But iteration will be quite fast.
However, what matters most is that you think about how much this matters. Is your game performance heavy at all? More specifically, is your game's performance going to be contingent on the memory performance of the class that contains your entities? If not, then what matters for you is user convenience. Do what it takes to get the job done. And if map
does the job, use it. If it starts to become a performance issue, you should be able to replace it with something else.