Here's a curiosity I've been investigating. The .NET Dictionary class performs ridiculously fast compared to the STL unordered_map in a test I keep running, and I can't figure out why.
(0.5 seconds vs. 4 seconds on my machine) (.NET 3.5 SP1 vs. Visual Studio 2008 Express SP1's STL)
On the other hand, if I implement my own hash table in C# and C++, the C++ version is about twice as fast as the C# one, which is fine because it reinforces my common sense that native machine code is sometimes faster. (See. I said "sometimes".) Me being the same person in both languages, I wonder what tricks was the C# coder from Microsoft able to play that the C++ coder from Microsoft wasn't? I'm having trouble imagining how a compiler could play such tricks on its own, going through the trouble of optimizing what should look to it to be arbitrary function calls.
It's a simple test, storing and retrieving integers.
C#:
const int total = (1 << 20);
int sum = 0;
Dictionary<int, int> dict = new Dictionary<int, int>();
for(int i = 0; i < total; i++)
{
dict.Add(i, i * 7);
}
for(int j = 0; j < (1 << 3); j++)
{
int i = total;
while(i > 0)
{
i--;
sum += dict[i];
}
}
Console.WriteLine(sum);
C++:
const int total = (1 << 20);
int sum = 0;
std::tr1::unordered_map<int, int> dict;
for(int i = 0; i < total; i++)
{
dict.insert(pair<int, int>(i, i * 7));
}
for(int j = 0; j < (1 << 3); j++)
{
int i = total;
while(i > 0)
{
i--;
std::tr1::unordered_map<int, int>::const_iterator found =
dict.find(i);
sum += found->second;
}
}
cout << sum << endl;
The trick is to use Robin Hood hashing with an upper limit on the number of probes. If an element has to be more than X positions away from its ideal position, you grow the table and hope that with a bigger table every element can be close to where it wants to be.
Simply put, using a hash table is faster than searching through an array. In the Find the First Non-Repeating Character algorithm challenge, we use hash tables as an optimal solution compared to nested for loops, which is a reduction in complexity from O(n*n) to O(n).
Hash tables tend to be faster when it comes to searching for items. In arrays, you have to loop over all items before you find what you are looking for while in a hash table you go directly to the location of the item. Inserting an item is also faster in Hash tables since you just hash the key and insert it.
This may be due to the cache size of your cpu. Once the cache fills up, the memory manager will have to page out data which gives a large performance hit. In addition to the locality issues, there are a number of other reasons why the supposed "order 1" performance of hashtables is a myth in any real world scenario.
the two versions are not equivalent , your are constructing an iterator in each pass of your C++ while loop. that takes CPU time and throws your results.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With