map hash_map unordered_map 性能测试_C/C++_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > C/C++ > map hash_map unordered_map 性能测试

map hash_map unordered_map 性能测试

 2013/6/19 11:18:52  aigo  程序员俱乐部  我要评论(0)
  • 摘要:原文:http://blog.chinaunix.net/uid-20384806-id-3055333.html测试条件:gccversion4.2.120070719[FreeBSD]FreeBSD7.2-RELEASE#0:FriMay107:18:07UTC2009root@driscoll.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERICamd64Intel(R)Xeon(R)CPUE5620@2.40GHz16核测试程序说明
  • 标签:has Map Hash 测试 性能测试
原文:http://blog.chinaunix.net/uid-20384806-id-3055333.html 测试条件: gcc version 4.2.1 20070719? [FreeBSD] FreeBSD ?7.2-RELEASE #0: Fri May? 1 07:18:07 UTC 2009???? root@driscoll.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC? amd64
Intel(R) Xeon(R) CPU?????????? E5620? @ 2.40GHz 16核 ? 测试程序说明: 先准备好n个字符串随机的MD5字符串做为key,然后分别对3个容器进行插入、遍历、查找、caozuo.html" target="_blank">删除操作。 例如,n=100的时候,插入是指插入100个随机MD5 key;遍历是指对容器遍历一次;查找是指分别对这个100个随机的MD5 key做查找操作(即查找100次);删除是指挨个删除这个100个随机MD5 key。 ? 测试数据如下表:
插入,单位us 100 1K 10K 100K 1M 10M std::map 241 2833 35888 381214 4439088 62233380 std::ext/hash_map 97 1667 16466 146025 1788446 18512639 std::tr1::unordered_map 77 772 8052 53094 658312 7429297 ?
遍历,单位us 100 1K 10K 100K 1M 10M std::map 11 76 842 11603 155700 1771906 std::ext/hash_map 47 430 4218 39880 470344 4781575 std::tr1::unordered_map 1 1 2 1 2 1 查找,单位us 100 1K 10K 100K 1M 10M std::map 156 2111 30456 258709 4100260 59064394 std::ext/hash_map 77 774 8056 56974 660231 7705527 std::tr1::unordered_map 77 772 8051 54456 659537 7600263 删除,单位us 100 1K 10K 100K 1M 10M std::map 291 3641 49584 472414 6675897 92491113 std::ext/hash_map 89 869 9068 86524 964767 10372650 std::tr1::unordered_map 49 480 4879 33087 395098 4369617 结论: 1. std::tr1::unordered_map 与?std::ext/hash_map? ? ? ?任何情况下,如果要在这两个容器之间选择的话,我们毫不犹豫应该选择 unordered_map。因为他的性能在上述4中操作中均优于 hash_map,甚至可以说远远优于 hash_map。 ? 2.?std::tr1::unordered_map 与?std::map? ? ? ?map的性能总体来说是最差的。但是,当我们需要一个有序的关联容器的时候,我们必须选择std::map,因为?unordered_map?内部元素不是有序的,这一点从名字都可以看出来。除此之外都应该选择?unordered_map?。 ? 3. 上述测试中,unordered_map?的遍历性能几乎是常数级别的,与常识不太相符,需要再研究研究。 ? 附录:贴上源代码 说明:与测试程序稍有区别,这里的源码里没有MD5相关的代码以确保其他人能比较方便的直接拿去编译运行。 ? 如有错误还请跟帖指出,非常感谢。 ? ?
    class="dp-css" style="margin-right: 1px; margin-bottom: 0px; margin-left: 1px; color: #5c5c5c; line-height: 1.3;">
  1. #include?<iostream>
  2. #include?<string>
  3. #include?<sstream>
  4. #include?<list>
  5. #include?<map>
  6. #include?<sys/time.h>
  7. #include?<ext/hash_map>
  8. #include?<tr1/unordered_map>
  9. namespace zl
  10. {?//{{{
  11. ????struct equal_to
  12. ????{
  13. ????????bool operator()(const?char*?s1,?const?char*?s2)?const
  14. ????????{
  15. ????????????return strcmp(s1,?s2)?==?0;
  16. ????????}
  17. ????};
  18. ?
  19. ????struct hash_string
  20. ????????:?public?std::unary_function<std::string,?std::size_t>
  21. ????????{
  22. ????????????std::size_t
  23. ????????????????operator()(const?std::string&?__s)?const
  24. #ifdef __linux__
  25. ????????????????{?return std::tr1::Fnv_hash<>::hash(__s.data(),?__s.length());?}
  26. #else
  27. ????????????????{?return std::tr1::_Fnv_hash<>::hash(__s.data(),?__s.length());?}
  28. #endif
  29. ????????};
  30. ????
  31. ????struct hash_charptr
  32. ????????:?public?std::unary_function<const?char*,?std::size_t>
  33. ????????{
  34. ????????????std::size_t
  35. ????????????????operator()(const?char*?__s)?const
  36. #ifdef __linux__
  37. ????????????????{?return std::tr1::Fnv_hash<>::hash(__s,?strlen(__s));?}
  38. #else
  39. ????????????????{?return std::tr1::_Fnv_hash<>::hash(__s,?strlen(__s));?}
  40. #endif
  41. ????????};
  42. }//}}}
  43. typedef std::list<std::string>?string_list;
  44. typedef std::map<std::string,?int>?string_map;
  45. typedef __gnu_cxx::hash_map<std::string,?int,?zl::hash_string>?string_hash_map;
  46. typedef std::tr1::unordered_map<std::string,?int>?string_unordered_map;
  47. void fill_list(string_list&?slist,?size_t count);
  48. uint64_t current_usec();
  49. int?main(?int?argc,?char*?argv[]?)
  50. {
  51. ????if?(argc?!=?2?&&?argc?!=?3)
  52. ????{
  53. ????????fprintf(stderr,?"Usage:%s test_count rehash\n",?argv[0]);
  54. ????????fprintf(stderr,?"For example:%s 10000 rehash\n",?argv[0]);
  55. ????????return?-1;
  56. ????}
  57. ????size_t count?=?atoi(argv[1]);
  58. ????bool rehash?=?false;
  59. ????if?(argc?==?3)
  60. ????{
  61. ????????rehash?=?true;
  62. ????}
  63. ????string_map smap;
  64. ????string_hash_map shash_map;
  65. ????string_unordered_map sunordered_map;
  66. ????if?(rehash)
  67. ????{
  68. ????????sunordered_map.rehash(count);
  69. ????}
  70. ????string_list slist;
  71. ????fill_list(slist,?count);
  72. ????uint64_t start?=?0;
  73. ????uint64_t?end?=?0;
  74. ????uint64_t map_insert_us?=?0;
  75. ????uint64_t hash_map_insert_us?=?0;
  76. ????uint64_t unordered_map_insert_us?=?0;
  77. ????uint64_t map_traverse_us?=?0;
  78. ????uint64_t hash_map_traverse_us?=?0;
  79. ????uint64_t unordered_map_traverse_us?=?0;
  80. ????uint64_t map_find_us?=?0;
  81. ????uint64_t hash_map_find_us?=?0;
  82. ????uint64_t unordered_map_find_us?=?0;
  83. ????uint64_t map_delete_us?=?0;
  84. ????uint64_t hash_map_delete_us?=?0;
  85. ????uint64_t unordered_map_delete_us?=?0;
  86. ????//?Insert test
  87. ????{//{{{
  88. ????????string_list::iterator it(slist.begin());
  89. ????????string_list::iterator ite(slist.end());
  90. ????????//map insert
  91. ????????start?=?current_usec();
  92. ????????for?(int?i?=?0;?it?!=?ite;?++it,?++i)
  93. ????????{
  94. ????????????smap[*it]?=?i;
  95. ????????}
  96. ????????end?=?current_usec();
  97. ????????map_insert_us?=?end?-?start;
  98. ????????//hash_map insert
  99. ????????it?=?slist.begin();
  100. ????????start?=?current_usec();
  101. ????????for?(int?i?=?0;?it?!=?ite;?++it,?++i)
  102. ????????{
  103. ????????????shash_map[*it]?=?i;
  104. ????????}
  105. ????????end?=?current_usec();
  106. ????????hash_map_insert_us?=?end?-?start;
  107. ????????//unordered_map insert
  108. ????????it?=?slist.begin();
  109. ????????start?=?current_usec();
  110. ????????for?(int?i?=?0;?it?!=?ite;?++it,?++i)
  111. ????????{
  112. ????????????shash_map[*it]?=?i;
  113. ????????}
  114. ????????end?=?current_usec();
  115. ????????unordered_map_insert_us?=?end?-?start;
  116. ????}//}}}
  117. ????//?Traverse test
  118. ????{//{{{
  119. ????????//map traverse?
  120. ????????{
  121. ????????????string_map::iterator it(smap.begin());
  122. ????????????string_map::iterator ite(smap.end());
  123. ????????????start?=?current_usec();
  124. ????????????for?(int?i?=?0;?it?!=?ite;?++it)
  125. ????????????{
  126. ????????????????i++;
  127. ????????????}
  128. ????????????end?=?current_usec();
  129. ????????????map_traverse_us?=?end?-?start;
  130. ????????}
  131. ????????//hash_map traverse?
  132. ????????{
  133. ????????????string_hash_map::iterator it(shash_map.begin());
  134. ????????????string_hash_map::iterator ite(shash_map.end());
  135. ????????????start?=?current_usec();
  136. ????????????for?(int?i?=?0;?it?!=?ite;?++it)
  137. ????????????{
  138. ????????????????i++;
  139. ????????????}
  140. ????????????end?=?current_usec();
  141. ????????????hash_map_traverse_us?=?end?-?start;
  142. ????????}
  143. ????????//unordered_map traverse?
  144. ????????{
  145. ????????????string_unordered_map::iterator it(sunordered_map.begin());
  146. ????????????string_unordered_map::iterator ite(sunordered_map.end());
  147. ????????????start?=?current_usec();
  148. ????????????for?(int?i?=?0;?it?!=?ite;?++it)
  149. ????????????{
  150. ????????????????i++;
  151. ????????????}
  152. ????????????end?=?current_usec();
  153. ????????????unordered_map_traverse_us?=?end?-?start;
  154. ????????}
  155. ????}//}}}
  156. ????//?Find test
  157. ????{//{{{
  158. ????????string_list::iterator it(slist.begin());
  159. ????????string_list::iterator ite(slist.end());
  160. ????????//map find
  161. ????????start?=?current_usec();
  162. ????????for?(int?i?=?0;?it?!=?ite;?++it,?++i)
  163. ????????{
  164. ????????????smap[*it]?=?i;
  165. ????????}
  166. ????????end?=?current_usec();
  167. ????????map_find_us?=?end?-?start;
  168. ????????//hash_map find
  169. ????????it?=?slist.begin();
  170. ????????start?=?current_usec();
  171. ????????for?(int?i?=?0;?it?!=?ite;?++it,?++i)
  172. ????????{
  173. ????????????shash_map[*it]?=?i;
  174. ????????}
  175. ????????end?=?current_usec();
  176. ????????hash_map_find_us?=?end?-?start;
  177. ????????//unordered_map find
  178. ????????it?=?slist.begin();
  179. ????????start?=?current_usec();
  180. ????????for?(int?i?=?0;?it?!=?ite;?++it,?++i)
  181. ????????{
  182. ????????????shash_map[*it]?=?i;
  183. ????????}
  184. ????????end?=?current_usec();
  185. ????????unordered_map_find_us?=?end?-?start;
  186. ????}//}}}
  187. ????//?Delete test
  188. ????{//{{{
  189. ????????string_list::iterator it(slist.begin());
  190. ????????string_list::iterator ite(slist.end());
  191. ????????//map delete
  192. ????????start?=?current_usec();
  193. ????????for?(int?i?=?0;?it?!=?ite;?++it,?++i)
  194. ????????{
  195. ????????????smap.erase(*it);
  196. ????????}
  197. ????????end?=?current_usec();
  198. ????????map_delete_us?=?end?-?start;
  199. ????????//hash_map delete
  200. ????????it?=?slist.begin();
  201. ????????start?=?current_usec();
  202. ????????for?(int?i?=?0;?it?!=?ite;?++it,?++i)
  203. ????????{
  204. ????????????shash_map.erase(*it);
  205. ????????}
  206. ????????end?=?current_usec();
  207. ????????hash_map_delete_us?=?end?-?start;
  208. ????????//unordered_map delete
  209. ????????it?=?slist.begin();
  210. ????????start?=?current_usec();
  211. ????????for?(int?i?=?0;?it?!=?ite;?++it,?++i)
  212. ????????{
  213. ????????????shash_map.erase(*it);
  214. ????????}
  215. ????????end?=?current_usec();
  216. ????????unordered_map_delete_us?=?end?-?start;
  217. ????}//}}}
  218. ????//stat output
  219. ????std::cout?<<?" insert, count "?<<?count?<<?std::endl;
  220. ????std::cout?<<?" std::map "?<<?map_insert_us?<<?" us\n";
  221. ????std::cout?<<?" std::ext/hash_map "?<<?hash_map_insert_us?<<?" us\n";
  222. ????std::cout?<<?"std::tr1::unordered_map "?<<?unordered_map_insert_us?<<?" us\n";
  223. ????std::cout?<<?"\n";
  224. ????std::cout?<<?" traverse, count "?<<?count?<<?std::endl;
  225. ????std::cout?<<?" std::map "?<<?map_traverse_us?<<?" us\n";
  226. ????std::cout?<<?" std::ext/hash_map "?<<?hash_map_traverse_us?<<?" us\n";
  227. ????std::cout?<<?"std::tr1::unordered_map "?<<?unordered_map_traverse_us?<<?" us\n";
  228. ????std::cout?<<?"\n";
  229. ????std::cout?<<?" find, count "?<<?count?<<?std::endl;
  230. ????std::cout?<<?" std::map "?<<?map_find_us?<<?" us\n";
  231. ????std::cout?<<?" std::ext/hash_map "?<<?hash_map_find_us?<<?" us\n";
  232. ????std::cout?<<?"std::tr1::unordered_map "?<<?unordered_map_find_us?<<?" us\n";
  233. ????std::cout?<<?"\n";
  234. ????std::cout?<<?" delete, count "?<<?count?<<?std::endl;
  235. ????std::cout?<<?" std::map "?<<?map_delete_us?<<?" us\n";
  236. ????std::cout?<<?" std::ext/hash_map "?<<?hash_map_delete_us?<<?" us\n";
  237. ????std::cout?<<?"std::tr1::unordered_map "?<<?unordered_map_delete_us?<<?" us\n";
  238. ?????
  239. ????return 0;
  240. }
  241. void fill_list(string_list&?slist,?size_t count)
  242. {
  243. ????for?(size_t i?=?0;?i?<?count;?++i)
  244. ????{
  245. ????????std::ostringstream oss;
  246. ????????oss?<<?i;
  247. ????????//slist.push_back(MD5::getHexMD5(oss.str().c_str(),?oss.str().length()));
  248. ????????slist.push_back(oss.str());
  249. ????}
  250. }
  251. uint64_t current_usec()
  252. {
  253. ????struct timeval tv;
  254. ????gettimeofday(?&tv,?NULL?);
  255. ????return tv.tv_sec?*?1000?*?1000?+?tv.tv_usec;
  256. }
发表评论
用户名: 匿名