Map Value Address

I have settings that are stored in std::map . For example, there is a WorldTime key with a value that updates each iteration of the main loop. I don’t want to read it from the map when I need it (it also processes every frame), I think it’s not fast. So, can I get a pointer to the value of the map and access it? Code:

 std::map<std::string, int> mSettings; // Somewhere in cycle: mSettings["WorldTime"] += 10; // ms // Somewhere in another place, also called in cycle DrawText(mSettings["WorldTime"]); // Is slow to call each frame 

So the idea is something like:

 int *time = &mSettings["WorldTime"]; // In cycle: DrawText(&time); 

How is that wrong? Should I do something like this?

+4
source share
3 answers

It is best to use the link:

 int & time = mSettings["WorldTime"]; 

If the key does not exist yet, [] -access will create the element (and value-initializes the displayed value, i.e. 0 for int ). Alternatively (if the key already exists):

 int & time = *mSettings.find("WorldTime"); 

On the sidelines: if you have hundreds of thousands of string keys or string key searches are used repeatedly, you may find that std::unordered_map<std::string, int> gives better results (but always a profile before making a decision). These two cards have almost identical interfaces for your purpose.

+5
source

According to fooobar.com/questions/17319 / ... , it is perfectly normal to store a pointer to a map element, since it will not be invalidated until the element is deleted (see note 3).

+3
source

If you're so worried about performance, why are you using key strings? What if you have an enumeration? Like this:

 enum Settings { WorldTime, ... }; 

Then your map will use int for keys, not strings. It should do comparisons between keys, because I believe that std :: map is implemented as a balanced tree. Comparing between ints is much faster than comparing strings.

Also, if you use an enumeration for keys, you can simply use an array, because an enumeration is essentially a map with some sort of character (i.e. WorldTime) up to an integer starting from zero. So do the following:

 enum Settings { WorldTime, ... NumSettings }; 

And then declare mSettings as an array:

 int mSettings[NumSettings]; 

Which has faster search time compared to std :: map. Then do the following:

 DrawText(mSettings[WorldTime]); 

Since you basically access the value in the array, not the map, it will be much faster and you won’t have to worry about what you tried to do in the first or second place.

+1
source

Source: https://habr.com/ru/post/1382596/


All Articles