Kolophonius
Kolophonius

Reputation: 13

Is there a reason to prefer multiple unordered_map of one variable over one of a struct?

I have a point class ("Point") containing 2d coordinates x and y. Now I want a 2d map with fields and I use unordered_map for it.

On each field of this map I want to save several values (e.g. type, height, etc.).

I realize I can either have another class/struct for this:

struct fieldData{
  int type;
  float height;
}
unordered_map<Point, fieldData> myMap;

Or I could have one unordered map for each:

unordered_map<Point, int> mapType;
unordered_map<Point, float> mapHeight;

My current reasoning is that the pros for doing it separately is that the access will be much faster since I only extract e.g. the type when I need the type and not both when I only need the type. If I use a struct the operation will always run on the full set of data. A field might contain a lot of data in the end and I might want to have the program run on limited machines, like a Raspberry Pi.

However, with many different variables for each field the code might get hard to maintain quickly.

Is it worth to do it separately or can I do the more convenient way?

Upvotes: 1

Views: 127

Answers (3)

isekaijin
isekaijin

Reputation: 19742

When you retrieve an element from a std::unordered_map, you always get a reference to, not a copy of the element. See here for the details. So, even if your unordered map's mapped_type is a very large struct, if you only need a single field, only that single field will be retrieved. The following two snippets are equivalent in terms of runtime performance:

   auto it = map.find(key);
   if( it != map.end())
   {
       LargeStruct * ls = &*it;
       do_something_with(ls->small_field);
   }

And:

   auto it = map.find(key);
   if( it != map.end())
   {
       LargeStruct & ls = *it;
       do_something_with(ls.small_field);
   }

And the latter is more idiomatic C++.

Upvotes: 4

Thomas Sparber
Thomas Sparber

Reputation: 2917

I don't think that two maps will be faster. Extracting a value always includes searching the map. So if you Need type and height you have to search twice (in two different maps). So in this case it is actually slower.

Also regarding Memory it is more efficient to use one map.

Upvotes: 0

Ami Tavory
Ami Tavory

Reputation: 76297

You should prefer a single *map:

  • the access to all fields will have a single access cost (e.g., in this case, a hash function call, mainly)

  • for a large number of fields, you might have better encapsulation with a struct (or at least tuple)

Upvotes: 1

Related Questions