我是靠谱客的博主 活泼萝莉,最近开发中收集的这篇文章主要介绍map, hash_map,unordered_map与性能测试,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

转自:http://blog.sina.com.cn/s/blog_59b6af690100xy0z.html

后半部分转自:http://blog.chinaunix.net/uid-20384806-id-3055333.html

Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。

下面举例说明什么是一对一的数据映射。比如一个班级中,每个学生的学号跟他的姓名就存在着一一映射的关系,这个模型用map可能轻易描述,很明显学号用int描述,姓名用字符串描述(本篇文章中不用char *来描述字符串,而是采用STL中string来描述),下面给出map描述代码:

Map<int, string> mapStudent;

1. map的构造函数

map共提供了6个构造函数,这块涉及到内存分配器这些东西,略过不表,在下面我们将接触到一些map的构造方法,这里要说下的就是,我们通常用如下方法构造一个map:

Map<int, string> mapStudent;

2. 数据的插入

在构造map容器后,我们就可以往里面插入数据了。这里讲三种插入数据的方法:

第一种:用insert函数插入pair数据,下面举例说明(以下代码虽然是随手写的,应该可以在VC和GCC下编译通过,大家可以运行下看什么效果,在VC下请加入这条语句,屏蔽4786警告#pragma warning (disable:4786) )

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent.insert(pair<int, string>(1, “student_one”));

mapStudent.insert(pair<int, string>(2, “student_two”));

mapStudent.insert(pair<int, string>(3, “student_three”));

map<int, string>::iterator iter;

for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)

{

Cout<<iter->first<<” ”<<iter->second<<end;

}

}

第二种:用insert函数插入value_type数据,下面举例说明

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent.insert(map<int, string>::value_type (1, “student_one”));

mapStudent.insert(map<int, string>::value_type (2, “student_two”));

mapStudent.insert(map<int, string>::value_type (3, “student_three”));

map<int, string>::iterator iter;

for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)

{

Cout<<iter->first<<” ”<<iter->second<<end;

}

}

第三种:用数组方式插入数据,下面举例说明

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent[1] = “student_one”;

mapStudent[2] = “student_two”;

mapStudent[3] = “student_three”;

map<int, string>::iterator iter;

for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)

{

Cout<<iter->first<<” ”<<iter->second<<end;

}

}

以上三种用法,虽然都可以实现数据的插入,但是它们是有区别的,当然了第一种和第二种在效果上是完成一样的,用insert函数插入数据,在数据的插入上涉及到集合的唯一性这个概念,即当map中有这个关键字时,insert操作是插入数据不了的,但是用数组方式就不同了,它可以覆盖以前该关键字对应的值,用程序说明

mapStudent.insert(map<int, string>::value_type (1, “student_one”));

mapStudent.insert(map<int, string>::value_type (1, “student_two”));

上面这两条语句执行后,map中1这个关键字对应的值是“student_one”,第二条语句并没有生效,那么这就涉及到我们怎么知道insert语句是否插入成功的问题了,可以用pair来获得是否插入成功,程序如下

Pair<map<int, string>::iterator, bool> Insert_Pair;

Insert_Pair = mapStudent.insert(map<int, string>::value_type (1, “student_one”));

我们通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map的迭代器,如果插入成功的话Insert_Pair.second应该是true的,否则为false。

下面给出完成代码,演示插入成功与否问题

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

Pair<map<int, string>::iterator, bool> Insert_Pair;

Insert_Pair = mapStudent.insert(pair<int, string>(1, “student_one”));

If(Insert_Pair.second == true)

{

Cout<<”Insert Successfully”<<endl;

}

Else

{

Cout<<”Insert Failure”<<endl;

}

Insert_Pair = mapStudent.insert(pair<int, string>(1, “student_two”));

If(Insert_Pair.second == true)

{

Cout<<”Insert Successfully”<<endl;

}

Else

{

Cout<<”Insert Failure”<<endl;

}

map<int, string>::iterator iter;

for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)

{

Cout<<iter->first<<” ”<<iter->second<<end;

}

}

大家可以用如下程序,看下用数组插入在数据覆盖上的效果

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent[1] = “student_one”;

mapStudent[1] = “student_two”;

mapStudent[2] = “student_three”;

map<int, string>::iterator iter;

for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)

{

Cout<<iter->first<<” ”<<iter->second<<end;

}

}

3. map的大小

在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下:

Int nSize = mapStudent.size();

4. 数据的遍历

这里也提供三种方法,对map进行遍历

第一种:应用前向迭代器,上面举例程序中到处都是了,略过不表

第二种:应用反相迭代器,下面举例说明,要体会效果,请自个动手运行程序

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent.insert(pair<int, string>(1, “student_one”));

mapStudent.insert(pair<int, string>(2, “student_two”));

mapStudent.insert(pair<int, string>(3, “student_three”));

map<int, string>::reverse_iterator iter;

for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)

{

Cout<<iter->first<<” ”<<iter->second<<end;

}

}

第三种:用数组方式,程序说明如下

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent.insert(pair<int, string>(1, “student_one”));

mapStudent.insert(pair<int, string>(2, “student_two”));

mapStudent.insert(pair<int, string>(3, “student_three”));

int nSize = mapStudent.size()

//此处有误,应该是 for(int nIndex = 1; nIndex <= nSize; nIndex++)


//by rainfish

for(int nIndex = 0; nIndex < nSize; nIndex++)

{

Cout<<mapStudent[nIndex]<<end;

}

}

5. 数据的查找(包括判定这个关键字是否在map中出现)

在这里我们将体会,map在数据插入时保证有序的好处。

要判定一个数据(关键字)是否在map中出现的方法比较多,这里标题虽然是数据的查找,在这里将穿插着大量的map基本用法。

这里给出三种数据查找方法

第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了

第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器,程序说明

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent.insert(pair<int, string>(1, “student_one”));

mapStudent.insert(pair<int, string>(2, “student_two”));

mapStudent.insert(pair<int, string>(3, “student_three”));

map<int, string>::iterator iter;

iter = mapStudent.find(1);

if(iter != mapStudent.end())

{

Cout<<”Find, the value is ”<<iter->second<<endl;

}

Else

{

Cout<<”Do not Find”<<endl;

}

}

第三种:这个方法用来判定数据是否出现,是显得笨了点,但是,我打算在这里讲解

Lower_bound函数用法,这个函数用来返回要查找关键字的下界(是一个迭代器)

Upper_bound函数用法,这个函数用来返回要查找关键字的上界(是一个迭代器)

例如:map中已经插入了1,2,3,4的话,如果lower_bound(2)的话,返回的2,而upper-bound(2)的话,返回的就是3

Equal_range函数返回一个pair,pair里面第一个变量是Lower_bound返回的迭代器,pair里面第二个迭代器是Upper_bound返回的迭代器,如果这两个迭代器相等的话,则说明map中不出现这个关键字,程序说明

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent[1] = “student_one”;

mapStudent[3] = “student_three”;

mapStudent[5] = “student_five”;

map<int, string>::iterator iter;

iter = mapStudent.lower_bound(2);

{

//返回的是下界3的迭代器

Cout<<iter->second<<endl;

}

iter = mapStudent.lower_bound(3);

{

//返回的是下界3的迭代器

Cout<<iter->second<<endl;

}

iter = mapStudent.upper_bound(2);

{

//返回的是上界3的迭代器

Cout<<iter->second<<endl;

}

iter = mapStudent.upper_bound(3);

{

//返回的是上界5的迭代器

Cout<<iter->second<<endl;

}

Pair<map<int, string>::iterator, map<int, string>::iterator> mapPair;

mapPair = mapStudent.equal_range(2);

if(mapPair.first == mapPair.second)
{

cout<<”Do not Find”<<endl;

}

Else

{

Cout<<”Find”<<endl;
}

mapPair = mapStudent.equal_range(3);

if(mapPair.first == mapPair.second)
{

cout<<”Do not Find”<<endl;

}

Else

{

Cout<<”Find”<<endl;
}

}

6. 数据的清空与判空

清空map中的数据可以用clear()函数,判定map中是否有数据可以用empty()函数,它返回true则说明是空map

7. 数据的删除

这里要用到erase函数,它有三个重载了的函数,下面在例子中详细说明它们的用法

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent.insert(pair<int, string>(1, “student_one”));

mapStudent.insert(pair<int, string>(2, “student_two”));

mapStudent.insert(pair<int, string>(3, “student_three”));

//如果你要演示输出效果,请选择以下的一种,你看到的效果会比较好

//如果要删除1,用迭代器删除

map<int, string>::iterator iter;

iter = mapStudent.find(1);

mapStudent.erase(iter);

//如果要删除1,用关键字删除

Int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0

//用迭代器,成片的删除

//一下代码把整个map清空

mapStudent.earse(mapStudent.begin(), mapStudent.end());

//成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合

//自个加上遍历代码,打印输出吧

}

8. 其他一些函数用法

这里有swap,key_comp,value_comp,get_allocator等函数,感觉到这些函数在编程用的不是很多,略过不表,有兴趣的话可以自个研究

9. 排序

这里要讲的是一点比较高深的用法了,排序问题,STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,因为上面的关键字是int 型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候过不去,下面给出两个方法解决这个问题

第一种:小于号重载,程序举例

#include <map>

#include <string>

Using namespace std;

Typedef struct tagStudentInfo

{

Int nID;

String strName;

}StudentInfo, *PStudentInfo; //学生信息

Int main()

{

int nSize;

//用学生信息映射分数

map<StudentInfo, int>mapStudent;

map<StudentInfo, int>::iterator iter;

StudentInfo studentInfo;

studentInfo.nID = 1;

studentInfo.strName = “student_one”;

mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));

studentInfo.nID = 2;

studentInfo.strName = “student_two”;

mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));

for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++)

cout<<iter->first.nID<<endl<<iter->first.strName<<endl<<iter->second<<endl;

}

以上程序是无法编译通过的,只要重载小于号,就OK了,如下:

Typedef struct tagStudentInfo

{

Int nID;

String strName;

Bool operator < (tagStudentInfo const& _A) const

{

//这个函数指定排序策略,按nID排序,如果nID相等的话,按strName排序

If(nID < _A.nID)return true;

If(nID == _A.nID) return strName.compare(_A.strName) < 0;

Return false;

}

}StudentInfo, *PStudentInfo; //学生信息

第二种:仿函数的应用,这个时候结构体中没有直接的小于号重载,程序说明

#include <map>

#include <string>

Using namespace std;

Typedef struct tagStudentInfo

{

Int nID;

String strName;

}StudentInfo, *PStudentInfo; //学生信息

Classs sort

{

Public:

Bool operator() (StudentInfo const &_A, StudentInfo const &_B) const

{

If(_A.nID < _B.nID) return true;

If(_A.nID == _B.nID) return _A.strName.compare(_B.strName) < 0;

Return false;

}

};

Int main()

{

//用学生信息映射分数

Map<StudentInfo, int, sort>mapStudent;

StudentInfo studentInfo;

studentInfo.nID = 1;

studentInfo.strName = “student_one”;

mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));

studentInfo.nID = 2;

studentInfo.strName = “student_two”;

mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));

}

10. 另外

由于STL是一个统一的整体,map的很多用法都和STL中其它的东西结合在一起,比如在排序上,这里默认用的是小于号,即less<>,如果要从大到小排序呢,这里涉及到的东西很多,在此无法一一加以说明。

还要说明的是,map中由于它内部有序,由红黑树保证,因此很多函数执行的时间复杂度都是log2N的,如果用map函数可以实现的功能,而STL Algorithm也可以完成该功能,建议用map自带函数,效率高一些。

下面说下,map在空间上的特性,否则,估计你用起来会有时候表现的比较郁闷,由于map的每个数据对应红黑树上的一个节点,这个节点在不保存你的数据时,是占用16个字节的,一个父节点指针,左右孩子指针,还有一个枚举值(标示红黑的,相当于平衡二叉树中的平衡因子),我想大家应该知道,这些地方很费内存了吧,不说了……


关于头文件的说明

[转]http://biancheng.dnbcw.info/c/170128.html

标准std中只有map,是使用平衡二叉树实现的,查找和添加的复杂度都为O(log(n)),
没有提供hash map,gnu c++提供了hash_map,是一个hash map的实现,查找和添加复杂
度均为O(1)。

#include <ext/hash_map>
#include <iostream>
#include <cstring>
using namespace std;
using namespace __gnu_cxx;
struct eqstr{
bool operator()(const char *s1, const char *s2)const{
return strcmp(s1,s2) == 0;
}
};
int main(){
hash_map<const char *,int,hash<const char *>,eqstr> months;
months["january"] = 31;
months["february"] = 28;
months["march"] = 31;
cout << "march -> " << months["march"] << endl;
}

不过gnu hash_map和c++ stl的api不兼容,c++ tr1(C++ Technical Report
1)作为标准的扩展,实现了hash map,提供了和stl兼容一致的api,称为unorder_map.在头文件
<tr1/unordered_map>中。另外c++ tr1还提供了 正则表达式、智能指针、hash table、
随机数生成器的功能。
#include <iostream>
#include <string>
#include <tr1/unordered_map>
using namespace std;
int main(){
typedef std::tr1::unordered_map<int,string> hash_map;
hash_map hm;
hm.insert(std::pair<int,std::string>(0,"Hello"));
hm[1] = "World";
for(hash_map::const_iterator it = hm.begin(); it != hm.end(); ++it){
cout << it->first << "-> " << it->second << endl;
}
return 0;
}


map hash_map unordered_map 性能测试

by zieckey


测试条件:
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个容器进行插入、遍历、查找、删除操作。
例如,n=100的时候,插入是指插入100个随机MD5 key;遍历是指对容器遍历一次;查找是指分别对这个100个随机的MD5 key做查找操作(即查找100次);删除是指挨个删除这个100个随机MD5 key。

测试数据如下表:

插入,单位us1001K10K100K1M10M
std::map241283335888381214443908862233380
std::ext/hash_map97166716466146025178844618512639
std::tr1::unordered_map777728052530946583127429297


遍历,单位us1001K10K100K1M10M
std::map1176842116031557001771906
std::ext/hash_map474304218398804703444781575
std::tr1::unordered_map112121

查找,单位us1001K10K100K1M10M
std::map156211130456258709410026059064394
std::ext/hash_map777748056569746602317705527
std::tr1::unordered_map777728051544566595377600263

删除,单位us1001K10K100K1M10M
std::map291364149584472414667589792491113
std::ext/hash_map8986990688652496476710372650
std::tr1::unordered_map494804879330873950984369617

结论:
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相关的代码以确保其他人能比较方便的直接拿去编译运行。

如有错误还请跟帖指出,非常感谢。


  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. struct hash_string
  19. : public std::unary_function<std::string, std::size_t>
  20. {
  21. std::size_t
  22. operator()(const std::string& __s) const
  23. #ifdef __linux__
  24. { return std::tr1::Fnv_hash<>::hash(__s.data(), __s.length());}
  25. #else
  26. { return std::tr1::_Fnv_hash<>::hash(__s.data(), __s.length());}
  27. #endif
  28. };


  29. struct hash_charptr
  30. : public std::unary_function<const char*, std::size_t>
  31. {
  32. std::size_t
  33. operator()(const char* __s)const
  34. #ifdef __linux__
  35. { return std::tr1::Fnv_hash<>::hash(__s, strlen(__s));}
  36. #else
  37. { return std::tr1::_Fnv_hash<>::hash(__s, strlen(__s));}
  38. #endif
  39. };
  40. }//}}}

  41. typedef std::list<std::string> string_list;
  42. typedef std::map<std::string,int> string_map;
  43. typedef __gnu_cxx::hash_map<std::string,int, zl::hash_string> string_hash_map;
  44. typedef std::tr1::unordered_map<std::string,int> string_unordered_map;

  45. void fill_list(string_list& slist, size_t count);
  46. uint64_t current_usec();

  47. int main(int argc, char* argv[])
  48. {
  49. if (argc!= 2&& argc!= 3)
  50. {
  51. fprintf(stderr,"Usage:%s test_count rehashn", argv[0]);
  52. fprintf(stderr,"For example:%s 10000 rehashn", argv[0]);
  53. return -1;
  54. }

  55. size_t count = atoi(argv[1]);
  56. bool rehash = false;
  57. if (argc== 3)
  58. {
  59. rehash = true;
  60. }

  61. string_map smap;
  62. string_hash_map shash_map;
  63. string_unordered_map sunordered_map;

  64. if (rehash)
  65. {
  66. sunordered_map.rehash(count);
  67. }

  68. string_list slist;
  69. fill_list(slist, count);

  70. uint64_t start = 0;
  71. uint64_t end = 0;

  72. uint64_t map_insert_us = 0;
  73. uint64_t hash_map_insert_us = 0;
  74. uint64_t unordered_map_insert_us = 0;

  75. uint64_t map_traverse_us = 0;
  76. uint64_t hash_map_traverse_us = 0;
  77. uint64_t unordered_map_traverse_us = 0;

  78. uint64_t map_find_us = 0;
  79. uint64_t hash_map_find_us = 0;
  80. uint64_t unordered_map_find_us = 0;

  81. uint64_t map_delete_us = 0;
  82. uint64_t hash_map_delete_us = 0;
  83. uint64_t unordered_map_delete_us = 0;



  84. // Insert test
  85. {//{{{
  86. string_list::iterator it(slist.begin());
  87. string_list::iterator ite(slist.end());

  88. //map insert
  89. start = current_usec();
  90. for (int i = 0; it != ite;++it,++i)
  91. {
  92. smap[*it]= i;
  93. }
  94. end = current_usec();
  95. map_insert_us = end - start;

  96. //hash_map insert
  97. it = slist.begin();
  98. start = current_usec();
  99. for (int i = 0; it != ite;++it,++i)
  100. {
  101. shash_map[*it]= i;
  102. }
  103. end = current_usec();
  104. hash_map_insert_us = end - start;

  105. //unordered_map insert
  106. it = slist.begin();
  107. start = current_usec();
  108. for (int i = 0; it != ite;++it,++i)
  109. {
  110. shash_map[*it]= i;
  111. }
  112. end = current_usec();
  113. unordered_map_insert_us = end - start;
  114. }//}}}

  115. // Traverse test
  116. {//{{{
  117. //map traverse
  118. {
  119. string_map::iterator it(smap.begin());
  120. string_map::iterator ite(smap.end());
  121. start = current_usec();
  122. for (int i = 0; it != ite;++it)
  123. {
  124. i++;
  125. }
  126. end = current_usec();
  127. map_traverse_us = end - start;
  128. }

  129. //hash_map traverse
  130. {
  131. string_hash_map::iterator it(shash_map.begin());
  132. string_hash_map::iterator ite(shash_map.end());
  133. start = current_usec();
  134. for (int i = 0; it != ite;++it)
  135. {
  136. i++;
  137. }
  138. end = current_usec();
  139. hash_map_traverse_us = end - start;
  140. }

  141. //unordered_map traverse
  142. {
  143. string_unordered_map::iterator it(sunordered_map.begin());
  144. string_unordered_map::iterator ite(sunordered_map.end());
  145. start = current_usec();
  146. for (int i = 0; it != ite;++it)
  147. {
  148. i++;
  149. }
  150. end = current_usec();
  151. unordered_map_traverse_us = end - start;
  152. }
  153. }//}}}

  154. // Find test
  155. {//{{{
  156. string_list::iterator it(slist.begin());
  157. string_list::iterator ite(slist.end());

  158. //map find
  159. start = current_usec();
  160. for (int i = 0; it != ite;++it,++i)
  161. {
  162. smap[*it]= i;
  163. }
  164. end = current_usec();
  165. map_find_us = end - start;

  166. //hash_map find
  167. it = slist.begin();
  168. start = current_usec();
  169. for (int i = 0; it != ite;++it,++i)
  170. {
  171. shash_map[*it]= i;
  172. }
  173. end = current_usec();
  174. hash_map_find_us = end - start;

  175. //unordered_map find
  176. it = slist.begin();
  177. start = current_usec();
  178. for (int i = 0; it != ite;++it,++i)
  179. {
  180. shash_map[*it]= i;
  181. }
  182. end = current_usec();
  183. unordered_map_find_us = end - start;
  184. }//}}}

  185. // Delete test
  186. {//{{{
  187. string_list::iterator it(slist.begin());
  188. string_list::iterator ite(slist.end());

  189. //map delete
  190. start = current_usec();
  191. for (int i = 0; it != ite;++it,++i)
  192. {
  193. smap.erase(*it);
  194. }
  195. end = current_usec();
  196. map_delete_us = end - start;

  197. //hash_map delete
  198. it = slist.begin();
  199. start = current_usec();
  200. for (int i = 0; it != ite;++it,++i)
  201. {
  202. shash_map.erase(*it);
  203. }
  204. end = current_usec();
  205. hash_map_delete_us = end - start;

  206. //unordered_map delete
  207. it = slist.begin();
  208. start = current_usec();
  209. for (int i = 0; it != ite;++it,++i)
  210. {
  211. shash_map.erase(*it);
  212. }
  213. end = current_usec();
  214. unordered_map_delete_us = end - start;
  215. }//}}}

  216. //stat output
  217. std::cout<<" insert, count " << count << std::endl;
  218. std::cout<<" std::map " << map_insert_us << " usn";
  219. std::cout<<" std::ext/hash_map " << hash_map_insert_us << " usn";
  220. std::cout<<"std::tr1::unordered_map " << unordered_map_insert_us << " usn";

  221. std::cout<<"n";
  222. std::cout<<" traverse, count " << count << std::endl;
  223. std::cout<<" std::map " << map_traverse_us << " usn";
  224. std::cout<<" std::ext/hash_map " << hash_map_traverse_us << " usn";
  225. std::cout<<"std::tr1::unordered_map " << unordered_map_traverse_us << " usn";

  226. std::cout<<"n";
  227. std::cout<<" find, count " << count << std::endl;
  228. std::cout<<" std::map " << map_find_us << " usn";
  229. std::cout<<" std::ext/hash_map " << hash_map_find_us << " usn";
  230. std::cout<<"std::tr1::unordered_map " << unordered_map_find_us << " usn";

  231. std::cout<<"n";
  232. std::cout<<" delete, count " << count << std::endl;
  233. std::cout<<" std::map " << map_delete_us << " usn";
  234. std::cout<<" std::ext/hash_map " << hash_map_delete_us << " usn";
  235. std::cout<<"std::tr1::unordered_map " << unordered_map_delete_us << " usn";


  236. return 0;
  237. }

  238. void fill_list(string_list& slist, size_t count)
  239. {
  240. for (size_t i = 0; i< count;++i)
  241. {
  242. std::ostringstream oss;
  243. oss << i;
  244. //slist.push_back(MD5::getHexMD5(oss.str().c_str(), oss.str().length()));
  245. slist.push_back(oss.str());
  246. }
  247. }


  248. uint64_t current_usec()
  249. {
  250. struct timeval tv;
  251. gettimeofday( &tv, NULL );
  252. return tv.tv_sec * 1000 * 1000 + tv.tv_usec;
  253. }

最后

以上就是活泼萝莉为你收集整理的map, hash_map,unordered_map与性能测试的全部内容,希望文章能够帮你解决map, hash_map,unordered_map与性能测试所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(84)

评论列表共有 0 条评论

立即
投稿
返回
顶部