{"id":5691,"date":"2019-05-29T05:58:16","date_gmt":"2019-05-29T05:58:16","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/more-special-friends-with-std-map-and-std-unordered-map\/"},"modified":"2023-08-20T14:24:33","modified_gmt":"2023-08-20T14:24:33","slug":"more-special-friends-with-std-map-and-std-unordered-map","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/more-special-friends-with-std-map-and-std-unordered-map\/","title":{"rendered":"More special Friends with std::map and std::unordered_map"},"content":{"rendered":"<p>Modern C++ has eight associative containers, but your special friends should be <span style=\"font-family: courier new, courier;\">std::map<\/span> and <span style=\"font-family: courier new, courier;\">std::unordered_map<\/span>. Why? Let me explain it in this post.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5686\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/book-159880_1280.png\" alt=\"book 159880 1280\" width=\"500\" height=\"374\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/book-159880_1280.png 1280w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/book-159880_1280-300x224.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/book-159880_1280-1024x766.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/book-159880_1280-768x574.png 768w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>In my last post, <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-std-array-and-std-vector-are-your-friends\">C++ Core Guidelines:&nbsp;&nbsp;<span style=\"font-family: courier new, courier;\">std::array<\/span> and <span style=\"font-family: courier new, courier;\">std::vector <\/span><\/a>are your friends; I stated: In 99 % of your use-cases, you are lovely with a <span style=\"font-family: courier new, courier;\">std::array<\/span> or a <span style=\"font-family: courier new, courier;\">std::vector. <\/span>A similar statement exists for associative containers: In 95 % of your use cases, you are lovely with a <span style=\"font-family: courier new, courier;\">std::map<\/span> or <span style=\"font-family: courier new, courier;\">std::unordered_map<\/span>.&nbsp; In seldom cases, you don&#8217;t need the value associated with the key. These are the missing 5 %. Before I begin this post and give an overview and numbers to both associative containers, here is my rule of thumb for today: <strong>If you want a container with a key\/value association and the keys should be ordered, use <span style=\"font-family: courier new, courier;\">std::map<\/span>; if not, use a <span style=\"font-family: courier new, courier;\">std::unordered_map<\/span>.<\/strong><\/p>\n<p>Here is the first overview. For more details, please read my previous posts about <a href=\"https:\/\/www.modernescpp.com\/index.php\/tag\/hashtabellen\">associative containers<\/a>.<\/p>\n<h2>The eight Variations<\/h2>\n<h2><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5040\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/OrderedVersusUnorderedContainers.png\" alt=\"OrderedVersusUnorderedContainers\" width=\"700\" height=\"298\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/OrderedVersusUnorderedContainers.png 955w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/OrderedVersusUnorderedContainers-300x128.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/11\/OrderedVersusUnorderedContainers-768x327.png 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/h2>\n<p>To get an ordering into the eight variations of associative containers, you have to answer three questions. Each question can be answered by yes or no. <span style=\"font-family: 'courier new', courier;\">2 ^ 3 == 8.<\/span> Here are the three questions:<\/p>\n<ol>\n<li>Is the container ordered?<\/li>\n<li>Does the key have an associated value?<\/li>\n<li>Are several identical keys possible?<\/li>\n<\/ol>\n<p>And here are the answers.<\/p>\n<ol>\n<li>When the container is not ordered, it&#8217;s called <span style=\"font-family: courier new, courier;\">unordered<\/span>.<\/li>\n<li>When the key does have a value associated, it&#8217;s called <span style=\"font-family: courier new, courier;\">map<\/span>; if not <span style=\"font-family: courier new, courier;\">set<\/span>.<\/li>\n<li>When the container can have more than one identical key, it&#8217;s called <span style=\"font-family: courier new, courier;\">multi<\/span>.<\/li>\n<\/ol>\n<p>When I speak of the ordered container, I mean the ordering of the keys.<\/p>\n<p>Maybe this taxonomy was too complicated. Let me give you a more straightforward picture.<\/p>\n<h3>A Phone Book<\/h3>\n<p>The eight variations are just different versions of a phone book. What is a phone book? A phone book is a sequence of key\/value pairs. You use the keys (family names) to get the values (phone numbers).<\/p>\n<p>The family names of a phone book can be ordered or unordered; the phone book can have a phone number associated with the family name or not and can have only one or more identical family names. If you want to store your mobile and landline numbers in a phone book, you are pretty happy that you can use two identical keys.<\/p>\n<p>The reason for this post is not to explain the associative containers: The reason is a different one. The access time to an ordered associative container is logarithmic, but the access time to an unordered associative container is amortized constant.&nbsp;<\/p>\n<\/p>\n<h2>Performance of a<span style=\"font-family: courier new, courier;\"> std::map<\/span> and a <span style=\"font-family: courier new, courier;\">std::unordered::map<\/span><\/h2>\n<p>What does amortized constant access time mean for an unordered associative container such as<span style=\"font-family: courier new, courier;\"> std::unordered_map<\/span>? It means that your query for a phone number is independent of the size of the phone book. Don&#8217;t you believe me? Let me show you a performance test.<\/p>\n<p>I have a phone book with roughly 89,000 entries. I will increase its size successively by ten until it has almost 89,000,000 entries. After each step, I will ask for all its phone numbers. This means I randomly use all family names.&nbsp;<\/p>\n<p>The following image shows you a part of the initial phone book. You can see the name\/number pairs separated by a colon and the name separated from the number by a comma.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5687\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/telebook.png\" alt=\"telebook\" width=\"600\" height=\"311\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/telebook.png 1087w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/telebook-300x155.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/telebook-1024x529.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/telebook-768x397.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>&nbsp;The program should be pretty easy to read.<\/p>\n<p>&nbsp;<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ telephoneBook.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;chrono&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;fstream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;map&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;random&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;regex&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;sstream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;string&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;unordered_map&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;vector&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">using<\/span> map <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>unordered_map<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>string, <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>;                   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n\r\nstd<span style=\"color: #555555;\">::<\/span>ifstream openFile(<span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&amp;<\/span> myFile){                  \r\n\r\n  std<span style=\"color: #555555;\">::<\/span>ifstream file(myFile, std<span style=\"color: #555555;\">::<\/span>ios<span style=\"color: #555555;\">::<\/span>in);\r\n  <span style=\"color: #006699; font-weight: bold;\">if<\/span> ( <span style=\"color: #555555;\">!<\/span>file ){\r\n    std<span style=\"color: #555555;\">::<\/span>cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Can't open file \"<\/span><span style=\"color: #555555;\">+<\/span> myFile <span style=\"color: #555555;\">+<\/span> <span style=\"color: #cc3300;\">\"!\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    exit(EXIT_FAILURE);\r\n  }\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> file;\r\n  \r\n}\r\n\r\nstd<span style=\"color: #555555;\">::<\/span>string readFile(std<span style=\"color: #555555;\">::<\/span>ifstream file){                        \r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>stringstream buffer;\r\n    buffer <span style=\"color: #555555;\">&lt;&lt;<\/span> file.rdbuf();\r\n    \r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> buffer.str();\r\n    \r\n}\r\n\r\nmap createTeleBook(<span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&amp;<\/span> fileCont){                 \r\n    \r\n    map teleBook; \r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>regex regColon(<span style=\"color: #cc3300;\">\":\"<\/span>);\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>sregex_token_iterator fileContIt(fileCont.begin(), fileCont.end(), regColon, <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span>);\r\n    <span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>sregex_token_iterator fileContEndIt;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>string entry;\r\n    std<span style=\"color: #555555;\">::<\/span>string key;\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> value;\r\n    <span style=\"color: #006699; font-weight: bold;\">while<\/span> (fileContIt <span style=\"color: #555555;\">!=<\/span> fileContEndIt){                               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n        entry <span style=\"color: #555555;\">=<\/span> <span style=\"color: #555555;\">*<\/span>fileContIt<span style=\"color: #555555;\">++<\/span>;\r\n        <span style=\"color: #006699; font-weight: bold;\">auto<\/span> comma <span style=\"color: #555555;\">=<\/span> entry.find(<span style=\"color: #cc3300;\">\",\"<\/span>);                                  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n        key <span style=\"color: #555555;\">=<\/span> entry.substr(<span style=\"color: #ff6600;\">0<\/span>, comma);\r\n        value <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>stoi(entry.substr(comma <span style=\"color: #555555;\">+<\/span> <span style=\"color: #ff6600;\">1<\/span>, entry.length() <span style=\"color: #555555;\">-<\/span><span style=\"color: #ff6600;\">1<\/span>));\r\n        teleBook[key] <span style=\"color: #555555;\">=<\/span> value;                                         <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    }\r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> teleBook;\r\n    \r\n}\r\n\r\nstd<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&gt;<\/span> getRandomNames(<span style=\"color: #006699; font-weight: bold;\">const<\/span> map<span style=\"color: #555555;\">&amp;<\/span> teleBook){    \r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&gt;<\/span> allNames;\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> pair<span style=\"color: #555555;\">:<\/span> teleBook) allNames.push_back(pair.first);   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>random_device randDev;\r\n    std<span style=\"color: #555555;\">::<\/span>mt19937 generator(randDev());\r\n \r\n    std<span style=\"color: #555555;\">::<\/span>shuffle(allNames.begin(), allNames.end(), generator);         <span style=\"color: #0099ff; font-style: italic;\">\/\/ (6)<\/span> \r\n    \r\n    <span style=\"color: #006699; font-weight: bold;\">return<\/span> allNames;\r\n}\r\n    \r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> measurePerformance(<span style=\"color: #006699; font-weight: bold;\">const<\/span> std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&gt;&amp;<\/span> names, map<span style=\"color: #555555;\">&amp;<\/span> m){   \r\n        \r\n    <span style=\"color: #006699; font-weight: bold;\">auto<\/span> start <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>chrono<span style=\"color: #555555;\">::<\/span>steady_clock<span style=\"color: #555555;\">::<\/span>now();\r\n    <span style=\"color: #006699; font-weight: bold;\">for<\/span> (<span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #006699; font-weight: bold;\">auto<\/span><span style=\"color: #555555;\">&amp;<\/span> name<span style=\"color: #555555;\">:<\/span> names) m[name];                              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (7)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>chrono<span style=\"color: #555555;\">::<\/span>duration<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;<\/span> dur<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>chrono<span style=\"color: #555555;\">::<\/span>steady_clock<span style=\"color: #555555;\">::<\/span>now() <span style=\"color: #555555;\">-<\/span> start;\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Access time: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> dur.count() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" seconds\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n}\r\n    \r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> main(<span style=\"color: #007788; font-weight: bold;\">int<\/span> argc, <span style=\"color: #007788; font-weight: bold;\">char<\/span><span style=\"color: #555555;\">*<\/span> argv[]){\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ get the filename<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>string myFile;\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> ( argc <span style=\"color: #555555;\">==<\/span> <span style=\"color: #ff6600;\">2<\/span> ){\r\n        myFile<span style=\"color: #555555;\">=<\/span> {argv[<span style=\"color: #ff6600;\">1<\/span>]};\r\n    }\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span>{\r\n        std<span style=\"color: #555555;\">::<\/span>cerr <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"Filename missing !\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n        exit(EXIT_FAILURE);\r\n    } \r\n  \r\n    std<span style=\"color: #555555;\">::<\/span>ifstream file <span style=\"color: #555555;\">=<\/span> openFile(myFile);\r\n  \r\n    std<span style=\"color: #555555;\">::<\/span>string fileContent <span style=\"color: #555555;\">=<\/span> readFile(std<span style=\"color: #555555;\">::<\/span>move(file));\r\n  \r\n    map teleBook <span style=\"color: #555555;\">=<\/span> createTeleBook(fileContent);\r\n  \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"teleBook.size(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>  teleBook.size() <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n    std<span style=\"color: #555555;\">::<\/span>vector<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span>string<span style=\"color: #555555;\">&gt;<\/span> randomNames <span style=\"color: #555555;\">=<\/span> getRandomNames(teleBook);\r\n  \r\n    measurePerformance(randomNames, teleBook); \r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Let me start with the main program. I open the file, read the content, create a phone book (<span style=\"font-family: courier new, courier;\">std::map<\/span> or <span style=\"font-family: courier new, courier;\">std::unordered_map<\/span>), get an arbitrary permutation of the family names, and make the performance test finally. Okay, this was too concise.<\/p>\n<p>Line 1 is the most interesting one. A <span style=\"font-family: 'courier new', courier;\">std::unordered_map<\/span> supports a superset of the interface of <span style=\"font-family: 'courier new', courier;\">a std::map<\/span>. This makes it quite convenient for me to make my performance test. I first did it by <span style=\"font-family: courier new, courier;\">using map = std::map&lt;std::string, int&gt;;<\/span> and then changed the line to <span style=\"font-family: courier new, courier;\">using map = std::unordered_map&lt;std::string, int&gt;;<\/span>.&nbsp; The according to relations holds for the pairs (<span style=\"font-family: courier new, courier;\">std::set\/std::unordered_set<\/span>),(<span style=\"font-family: courier new, courier;\">std::mulitset, std::unordered_multiset<\/span>), and (<span style=\"font-family: courier new, courier;\">std::multimap, std::unordered_multimap<\/span>). I assume the following functions are also quite interesting for you:<\/p>\n<ul>\n<li><span style=\"font-family: courier new, courier;\">createTeleBook<\/span>\n<ul>\n<li>the <span style=\"font-family: courier new, courier;\">while<\/span> loop iterates over all name\/number tokens created by the regular expression<span style=\"font-family: courier new, courier;\"> regColon <\/span>(line 2)<\/li>\n<li>each token is separated by a comma (line 3)<\/li>\n<li>in the end, the name\/number pair is added to the phone book (line 4)<\/li>\n<\/ul>\n<\/li>\n<li><span style=\"font-family: courier new, courier;\">getRandomNames<\/span>\n<ul>\n<li>puts all names onto a vector (line 5)<\/li>\n<li>shuffles the names (line 6)<\/li>\n<\/ul>\n<\/li>\n<li><span style=\"font-family: courier new, courier;\">measurePerformance<\/span>\n<ul>\n<li>asks for each name in the phone book (line 7)<\/li>\n<\/ul>\n<div>&nbsp;<\/div>\n<\/li>\n<\/ul>\n<p>And now, finally, the performance numbers for a std<span style=\"font-family: courier new, courier;\">:<\/span>:map and a std<span style=\"font-family: courier new, courier;\">::unordered_map<\/span>.<\/p>\n<h3><span style=\"font-family: courier new, courier;\">std::map<\/span><\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5688\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/telebookMap.png\" alt=\"telebookMap\" width=\"450\" height=\"427\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/telebookMap.png 521w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/telebookMap-300x284.png 300w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><\/p>\n<h3><span style=\"font-family: courier new, courier;\">std::unordered_map<\/span><\/h3>\n<h3>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5689\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/telebookUnordered.png\" alt=\"telebookUnordered\" width=\"450\" height=\"369\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/telebookUnordered.png 602w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/telebookUnordered-300x246.png 300w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><\/h3>\n<p>The screenshots show precisely how big the phone books are. The numbers confirm the access time I showed in the first table: The access time of a <span style=\"font-family: 'courier new', courier;\">std::map<\/span> depends logarithmic on its size, and the access time of a <span style=\"font-family: 'courier new', courier;\">std::unordered_map<\/span> is amortised constant. The following plot shows the performance relation between a <span style=\"font-family: 'courier new', courier;\">std::map<\/span> and a <span style=\"font-family: 'courier new', courier;\">std::unordered_map<\/span>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5690\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/comparison.png\" alt=\"comparison\" width=\"640\" height=\"480\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/comparison.png 640w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/05\/comparison-300x225.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<p>For 100,000 entries, the <span style=\"font-family: courier new, courier;\">std::map<\/span> is three times slower than the <span style=\"font-family: courier new, courier;\">std::unordered_map<\/span>, and for 100,000,000 entries 7 1\/2 times slower.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>After this slight detour from the C++ core guidelines, I will write in my <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-avoid-bound-errors\">next post<\/a> about bounds errors and how to avoid them.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Modern C++ has eight associative containers, but your special friends should be std::map and std::unordered_map. Why? Let me explain it in this post.<\/p>\n","protected":false},"author":21,"featured_media":5686,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[472,470],"class_list":["post-5691","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-associative-containers","tag-performance"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5691","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5691"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5691\/revisions"}],"predecessor-version":[{"id":6786,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5691\/revisions\/6786"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5686"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5691"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5691"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5691"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}