tags:

views:

377

answers:

3

i've created a dll for gamemaker. dll's arrays where really slow so after asking around a bit i learnt i could use maps in c++ and make a dll.

anyway, ill represent what i need to store in a 3d array: information[id][number][number] the id corresponds to an objects id. the first number field ranges from 0 - 3 and each number represents a different setting. the 2nd number field represents the value for the setting in number field 1. so..

information[101][1][4]; 
information[101][2][4]; 
information[101][3][4];

this would translate to "object with id 101 has a value of 4 for settings 1, 2 and 3". i did this to try and copy it with maps:

//declared as a class member
map<double,  map<int, double>*> objIdMap;

///// lower down the page, in some function
map<int, double> objSettingsMap;
objSettingsMap[1] = 4;
objSettingsMap[2] = 4;
objSettingsMap[3] = 4;
map<int, double>* temp = &objSettingsMap;
objIdMap[id] = temp;

so the first map, objIdMap stores the id as the key, and a pointer to another map which stores the number representing the setting as the key, and the value of the setting as the value.

however, this is for a game, so new objects with their own id's and settings might need to be stored (sometimes a hundred or so new ones every few seconds), and the existing ones constantly need to retrieve the values for every step of the game. are maps not able to handle this? i has a very similar thing going with game maker's array's and it worked fine.

+1  A: 

1) Your code is buggy: You store a pointer to a local object objSettingsMap which will be destroyed as soon as it goes out of scope. You must store a map obj, not a pointer to it, so the local map will be copied into this object.

2) Maps can become arbitrarily large (i have maps with millions of entrys). If you need speed try hash_maps (part of C++0x, but also available from other sources), which are considerably faster. But adding some hundred entries each second shouldn't be a problem. But befre worring about execution speed you should always use a profiler.

3) I am not really sure if your nested structures MUST be maps. Depending of what number of setting you have, and what values they may have, a structure or bitfield or a vector might be more accurate.

RED SOFT ADAIR
right now i have " map<double, map<int, double>*> objIdMap;". what should i put into the value field instead of map<int, double>* ? it doesnt seem to like "map<double, map<int, double>>"
Prodigga
The map type should be map<double, map<int, double> > objIdMap;Make sure to keep a space between the two "> >". Otherwise it becomes the shift operator ">>".
RED SOFT ADAIR
love it. works wonderfully now. phew i was so scared... :D thanks
Prodigga
!!! Beware of doubles, they bite and they bite hard. You should always avoid comparing doubles directly, and you should avoid using them as keys into associative containers. You might find that you don't find elements that do exist in the map due to comparisson problems.
David Rodríguez - dribeas
@dribeas Very good point. I had to replace some code that used doubles as a key in a map, and the problem was that lookups arbitrarily failed. If you insist on going this route, you might be able to make it work by providing your own comparison operator which compares using epsilon (or similar)
pxb
Nothing wrong with sticking a pointer to a stack object in another object. They are both defined within the same scope so the first object (being placed inside the map) will be destroyed after the second object (the map holding the pointers). So there is no problem with the code as it stands.
Martin York
In the sample, yes.But itspropably intended to be extracted to non local object. He wrote,he had probloems with the syntaxof > >.
RED SOFT ADAIR
+2  A: 

Do not use double's as a the key of a map. Try to use a floating point comparison function if you want to compare two doubles.

TimW
Why not? A bit of an explanation, perhaps with some references would help.
Dominic Rodger
this did not help
Prodigga
In many cases you will find out that two doubles that are obviously the same (to the programmer) are different for the processor due to rounding errors if the operations to obtain them were different, or even if the operations were the same the FPU might have more bits (current intel compilers have 80 bit registers for 64 bit doubles) than doubles and then comparing the value dumped to memory with the value still in the register will yield false.
David Rodríguez - dribeas
Explanation and more discussion here:http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htmYou should also find more information by searching stackoverflow
pxb
@Dominic: doubles are 64bit, it's highly unlikely that you really need a namespace that wide. doubles are also, in the end, unprecise and if they're result of calculation they might end up different from previous calculations. double comparison is also fairly slow in some cases and have to wait for math coprocessor to finish whatever it is doing.
Pasi Savolainen
A: 

If you need really fast associative containers, try to learn about hashes. Maps are 'fast enough' but not brilliant for some cases.

Try to analyze what is the structure of objects you need to store. If the fields are fixed I'd recommend not to use nested maps. At all. Maps are usually intended for 'average' number of indexes. For low number simple lists are more effective because of insert / erase operations lower complexity. For great number of indexes you really need to think about hashing.

Don't forget about memory. std::map is highly dynamic template so on small objects stored you loose tons of memory because of dynamic allocation. Is it what you are really expecting? Once I was involved in std::map usage removal which lowered memory requirements in about 2 times.

If you only need to fill the map at startup and only search for elements (don't need to change structure) I'd recommend simple std::vector with sort applied after all the elems inserted. And then you can just use binary search (as you have sorted vector). Why? std::vector is much more predictable thing. The biggest advantage is continuous memory area.

Roman Nikitchenko
yea i do need to keep adding data. data is and added ALOT during run time. i got it all working now, and if i add 1 bit off data per step (per frame in the game) it works fine. but once i do 2 at a time, i see performance drops. i looked into this hash stuff but couldn't find alot on it. just an fyi, the number of items stores will probably never exceed 2000~ or so. so i guess it is fairly small scaled..
Prodigga