3
std::map<string, int> dict;
for(int i = 0; i < 300; ++i)
{
    dict["afsfgsdg"] = i*i;
    dict["5t3rfb"] = i;
    dict["fddss"] = i-1;
    dict["u4ffd"] = i/3;
    dict["vgfd3"] = i%3;
}

Since the string values are already known at compile time, will the compiler hash them at compile time, instead of hashing those string at run time ?

jokoon
  • 6,207
  • 11
  • 48
  • 85

3 Answers3

6

std::map doesn't hash anything. It uses comparisons to find elements, and its O(lg n) bound is for the number of comparisons needed when there are n keys in the map. It does not express anything about the cost of the comparisons themselves.

I.e. the program might use some short-circuited string comparisons, by doing a pointer comparison first, but the number of comparisons will stay logarithmic in the worst case (when the item is at one of the leaves in the tree, for the typical red-black tree implementation).

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
3

will the compiler hash them at compile time, instead of hashing those string at run time ?

No, because std::map doesn't use hashing, it is a red-black tree or similar binary tree.

It performs a lookup in the tree every time.

First the compiler will convert "afsfgsdg" to a std::string, then do an O(log n) search for the string in the map.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
1

Analyzing algorithms for asymptotic performance is working on the operations that must be performed and the cost they add to the equation. For that you need to first know what are the performed operations and then evaluate its costs.

Searching for a key in a balanced binary tree (which maps happen to be) require O( log N ) complex operations. Each of those operations implies comparing the key for a match and following the appropriate pointer (child) if the key did not match. This means that the overall cost is proportional to log N times the cost of those two operations. Following pointers is a constant time operation O(1), and comparing keys depend on the key. For an integer key, comparisons are fast O(1). Comparing two strings is another story, it takes time proportional to the sizes of the strings involved O(L) (where I have used intentionally L as the length of string parameter instead of the more common N.

When you sum all the costs up you get that using integers as keys the total cost is O( log N )*( O(1) + O(1) ) that is equivalent to O( log N ). (O(1) gets hidden in the constant that the O notation silently hides.

If you use strings as keys, the total cost is O( log N )*( O(L) + O(1) ) where the constant time operation gets hidden by the more costly linear operation O(L) and can be converted into O( L * log N ). That is, the cost of locating an element in a map keyed by strings is proportional to the logarithm of the number of elements stored in the map times the average length of the strings used as keys.

learner
  • 1,952
  • 7
  • 33
  • 62