开发者

Why is my unordered_map ordering itself?

So I was playing with the newly standardized unordered_map from the STL. The code I have is kinda开发者_开发问答 like this, I just create an unordered_map, fill it up, and print it out:

    unordered_map<int,string> m1;

    m1[5]="lamb";
    m1[2]="had";
    m1[3]="a";
    m1[1]="mary";
    m1[4]="little";
    m1[7]="fleece";
    m1[6]="whose";
    m1[10]="fleecey";
    m1[8]="was";
    m1[9]="all";

for(unordered_map<int,string>::const_iterator i = m1.begin(); i != m1.end(); ++i)
cout<<i->first<<" "<<i->second<<endl;

However, the output I get is ordered thusly:

1 mary
2 had
3 a
4 little
5 lamb
6 whose
7 fleece
8 was
9 all
10 fleecey

But I don't want to pay the price to have my map ordered! That is why I am using an unordered_map... What is going on here?

additional note: I am using gcc version 4.3.4 20090804 (release) 1 (GCC) and am compiling like this g++ -std=c++0X maptest.cpp


"Unordered" doesn't mean it will store the items randomly or maintain the order you put them in the map. It just means you can't rely on any particular ordering. You don't pay a price for ordering, quite the contrary - the implementation isn't explicitly ordering the items, it's a hashmap and stores its elements in whatever way it pleases, which usually is a pretty performant way. It just so happens that the the hashing algorithm and other internal workings of the map, when using exactly these keys and this number and order of operations on the map, end up storing the items in a order that looks ordered. Strings, for example, may lead to an apparently randomized layout.

On a side note, this is probably caused by the map using a hash that maps (at least some) integers to itself and using the lower bits (as many as the map size mandates) of the hash the to determine the index for the underlying array (for instance, CPython does this - with some very clever additions to handle collisions relatively simply and efficiently; for the same reason the hashes of CPython strings and tuples are very predictable).


For your amusement, here's the output from libc++, which also has an identity function for std::hash<int>.

9 all
8 was
10 fleecey
6 whose
7 fleece
4 little
1 mary
3 a
2 had
5 lamb

There are several ways to implement a hash container, each with its own tradeoffs.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜