boost:unordered_map和std::map的使用详解和性能比较
2015-05-12 11:29
519 查看
今天看到 boost::unordered_map, 它与 stl::map的区别就是,stl::map是按照operator<比较判断元素是否相同,以及比较元素的大小,然后选择合适的位置插入到树中。所以,如果对map进行遍历(中序遍历)的话,输出的结果是有序的。顺序就是按照operator<
定义的大小排序。
而boost::unordered_map是计算元素的Hash值,根据Hash值判断元素是否相同。所以,对unordered_map进行遍历,结果是无序的。
用法的区别就是,stl::map 的key需要定义operator< 。 而boost::unordered_map需要定义hash_value函数并且重载operator==。对于内置类型,如string,这些都不用操心。对于自定义的类型做key,就需要自己重载operator<
或者hash_value()了。
最后,说,当不需要结果排好序时,最好用unordered_map。
其实,stl::map对于与java中的TreeMap,而boost::unordered_map对应于java中的HashMap //Java我不是很熟,这个不确定是否正确
stl::map
[cpp]
#include<string>
#include<iostream>
#include<map>
using namespace std;
struct person
{
string name;
int age;
person(string name, int age)
{
this->name = name;
this->age = age;
}
bool operator < (const person& p) const
{
return this->age < p.age;
}
};
map<person,int> m;
int main()
{
person p1("Tom1",20);
person p2("Tom2",22);
person p3("Tom3",22);
person p4("Tom4",23);
person p5("Tom5",24);
m.insert(make_pair(p3, 100));
m.insert(make_pair(p4, 100));
m.insert(make_pair(p5, 100));
m.insert(make_pair(p1, 100));
m.insert(make_pair(p2, 100));
for(map<person, int>::iterator iter = m.begin(); iter != m.end(); iter++)
{
cout<<iter->first.name<<"\t"<<iter->first.age<<endl;
}
return 0;
}
output:
Tom1 20
Tom3 22
Tom4 23
Tom5 24
operator<的重载一定要定义成const。因为map内部实现时调用operator<的函数好像是const。
由于operator<比较的只是age,所以因为Tom2和Tom3的age相同,所以最终结果里面只有Tom3,没有Tom2
boost::unordered_map
[cpp]
#include<string>
#include<iostream>
#include<boost/unordered_map.hpp>
using namespace std;
struct person
{
string name;
int age;
person(string name, int age)
{
this->name = name;
this->age = age;
}
bool operator== (const person& p) const
{
return name==p.name && age==p.age;
}
};
size_t hash_value(const person& p)
{
size_t seed = 0;
boost::hash_combine(seed, boost::hash_value(p.name));
boost::hash_combine(seed, boost::hash_value(p.age));
return seed;
}
int main()
{
typedef boost::unordered_map<person,int> umap;
umap m;
person p1("Tom1",20);
person p2("Tom2",22);
person p3("Tom3",22);
person p4("Tom4",23);
person p5("Tom5",24);
m.insert(umap::value_type(p3, 100));
m.insert(umap::value_type(p4, 100));
m.insert(umap::value_type(p5, 100));
m.insert(umap::value_type(p1, 100));
m.insert(umap::value_type(p2, 100));
for(umap::iterator iter = m.begin(); iter != m.end(); iter++)
{
cout<<iter->first.name<<"\t"<<iter->first.age<<endl;
}
return 0;
}
输出
Tom1 20
Tom5 24
Tom4 23
Tom2 22
Tom3 22
必须要自定义operator==和hash_value。 重载operator==是因为,如果两个元素的hash_value的值相同,并不能断定这两个元素就相同,必须再调用operator==。
当然,如果hash_value的值不同,就不需要调用operator==了。
以上抄之
/article/11314830.html,自己也跑过,无误!
下边谈谈boost::unorder_map和std::map在插入和查找方面的性能
int main(int argc,int** argv)
{
time_t beginTime_1 = time(0);
boost::unordered_map<int, int> test_hash;
for (int i = 0; i < 5000000; i++)
{
test_hash.insert(std::pair<int, int>(i, i));
}
std::cout << test_hash.size() << std::endl;
time_t endTime_1 = time(0);
for (int i = 0; i< 5000001; ++i)
{
boost::unordered_map<int, int>::iterator iter = test_hash.find(i);
if (iter == test_hash.end())
{
std::cout << "false" << std::endl;
}
}
time_t endTime_2 = time(0);
std::cout << "unorderMap insert 50000000 cost time: " << endTime_1 - beginTime_1 << std::endl;
std::cout << "unorderMap find 50000000 cost time " << endTime_2 - endTime_1 << std::endl;
{
time_t first_time = time(0);
std::map<int, int> test_hash;
for (int i = 0; i < 5000000; i++)
{
test_hash.insert(std::pair<int, int>(i, i));
}
std::cout << test_hash.size() << std::endl;
time_t second_time = time(0);
for (int i = 0; i< 5000001; ++i)
{
std::map<int, int>::iterator iter = test_hash.find(i);
if (iter == test_hash.end())
{
std::cout << "false" << std::endl;
}
}
time_t third_time = time(0);
std::cout << "std::map insert 50000000 cost time: " << second_time - first_time << std::endl;
std::cout << "std::map find 50000000 cost time " << third_time - second_time << std::endl;
}
system("pause");
return 0;
}
结果:
今天看到 boost::unordered_map, 它与 stl::map的区别就是,stl::map是按照operator<比较判断元素是否相同,以及比较元素的大小,然后选择合适的位置插入到树中。所以,如果对map进行遍历(中序遍历)的话,输出的结果是有序的。顺序就是按照operator<
定义的大小排序。
而boost::unordered_map是计算元素的Hash值,根据Hash值判断元素是否相同。所以,对unordered_map进行遍历,结果是无序的。
用法的区别就是,stl::map 的key需要定义operator< 。 而boost::unordered_map需要定义hash_value函数并且重载operator==。对于内置类型,如string,这些都不用操心。对于自定义的类型做key,就需要自己重载operator<
或者hash_value()了。
最后,说,当不需要结果排好序时,最好用unordered_map。
其实,stl::map对于与java中的TreeMap,而boost::unordered_map对应于java中的HashMap //Java我不是很熟,这个不确定是否正确
stl::map
[cpp]
#include<string>
#include<iostream>
#include<map>
using namespace std;
struct person
{
string name;
int age;
person(string name, int age)
{
this->name = name;
this->age = age;
}
bool operator < (const person& p) const
{
return this->age < p.age;
}
};
map<person,int> m;
int main()
{
person p1("Tom1",20);
person p2("Tom2",22);
person p3("Tom3",22);
person p4("Tom4",23);
person p5("Tom5",24);
m.insert(make_pair(p3, 100));
m.insert(make_pair(p4, 100));
m.insert(make_pair(p5, 100));
m.insert(make_pair(p1, 100));
m.insert(make_pair(p2, 100));
for(map<person, int>::iterator iter = m.begin(); iter != m.end(); iter++)
{
cout<<iter->first.name<<"\t"<<iter->first.age<<endl;
}
return 0;
}
#include<string> #include<iostream> #include<map> using namespace std; struct person { string name; int age; person(string name, int age) { this->name = name; this->age = age; } bool operator < (const person& p) const { return this->age < p.age; } }; map<person,int> m; int main() { person p1("Tom1",20); person p2("Tom2",22); person p3("Tom3",22); person p4("Tom4",23); person p5("Tom5",24); m.insert(make_pair(p3, 100)); m.insert(make_pair(p4, 100)); m.insert(make_pair(p5, 100)); m.insert(make_pair(p1, 100)); m.insert(make_pair(p2, 100)); for(map<person, int>::iterator iter = m.begin(); iter != m.end(); iter++) { cout<<iter->first.name<<"\t"<<iter->first.age<<endl; } return 0; }
output:
Tom1 20
Tom3 22
Tom4 23
Tom5 24
operator<的重载一定要定义成const。因为map内部实现时调用operator<的函数好像是const。
由于operator<比较的只是age,所以因为Tom2和Tom3的age相同,所以最终结果里面只有Tom3,没有Tom2
boost::unordered_map
[cpp]
#include<string>
#include<iostream>
#include<boost/unordered_map.hpp>
using namespace std;
struct person
{
string name;
int age;
person(string name, int age)
{
this->name = name;
this->age = age;
}
bool operator== (const person& p) const
{
return name==p.name && age==p.age;
}
};
size_t hash_value(const person& p)
{
size_t seed = 0;
boost::hash_combine(seed, boost::hash_value(p.name));
boost::hash_combine(seed, boost::hash_value(p.age));
return seed;
}
int main()
{
typedef boost::unordered_map<person,int> umap;
umap m;
person p1("Tom1",20);
person p2("Tom2",22);
person p3("Tom3",22);
person p4("Tom4",23);
person p5("Tom5",24);
m.insert(umap::value_type(p3, 100));
m.insert(umap::value_type(p4, 100));
m.insert(umap::value_type(p5, 100));
m.insert(umap::value_type(p1, 100));
m.insert(umap::value_type(p2, 100));
for(umap::iterator iter = m.begin(); iter != m.end(); iter++)
{
cout<<iter->first.name<<"\t"<<iter->first.age<<endl;
}
return 0;
}
#include<string> #include<iostream> #include<boost/unordered_map.hpp> using namespace std; struct person { string name; int age; person(string name, int age) { this->name = name; this->age = age; } bool operator== (const person& p) const { return name==p.name && age==p.age; } }; size_t hash_value(const person& p) { size_t seed = 0; boost::hash_combine(seed, boost::hash_value(p.name)); boost::hash_combine(seed, boost::hash_value(p.age)); return seed; } int main() { typedef boost::unordered_map<person,int> umap; umap m; person p1("Tom1",20); person p2("Tom2",22); person p3("Tom3",22); person p4("Tom4",23); person p5("Tom5",24); m.insert(umap::value_type(p3, 100)); m.insert(umap::value_type(p4, 100)); m.insert(umap::value_type(p5, 100)); m.insert(umap::value_type(p1, 100)); m.insert(umap::value_type(p2, 100)); for(umap::iterator iter = m.begin(); iter != m.end(); iter++) { cout<<iter->first.name<<"\t"<<iter->first.age<<endl; } return 0; }
输出
Tom1 20
Tom5 24
Tom4 23
Tom2 22
Tom3 22
必须要自定义operator==和hash_value。 重载operator==是因为,如果两个元素的hash_value的值相同,并不能断定这两个元素就相同,必须再调用operator==。
当然,如果hash_value的值不同,就不需要调用operator==了。
以上抄之
/article/11314830.html,自己也跑过,无误!
下边谈谈boost::unorder_map和std::map在插入和查找方面的性能
int main(int argc,int** argv)
{
time_t beginTime_1 = time(0);
boost::unordered_map<int, int> test_hash;
for (int i = 0; i < 5000000; i++)
{
test_hash.insert(std::pair<int, int>(i, i));
}
std::cout << test_hash.size() << std::endl;
time_t endTime_1 = time(0);
for (int i = 0; i< 5000001; ++i)
{
boost::unordered_map<int, int>::iterator iter = test_hash.find(i);
if (iter == test_hash.end())
{
std::cout << "false" << std::endl;
}
}
time_t endTime_2 = time(0);
std::cout << "unorderMap insert 50000000 cost time: " << endTime_1 - beginTime_1 << std::endl;
std::cout << "unorderMap find 50000000 cost time " << endTime_2 - endTime_1 << std::endl;
{
time_t first_time = time(0);
std::map<int, int> test_hash;
for (int i = 0; i < 5000000; i++)
{
test_hash.insert(std::pair<int, int>(i, i));
}
std::cout << test_hash.size() << std::endl;
time_t second_time = time(0);
for (int i = 0; i< 5000001; ++i)
{
std::map<int, int>::iterator iter = test_hash.find(i);
if (iter == test_hash.end())
{
std::cout << "false" << std::endl;
}
}
time_t third_time = time(0);
std::cout << "std::map insert 50000000 cost time: " << second_time - first_time << std::endl;
std::cout << "std::map find 50000000 cost time " << third_time - second_time << std::endl;
}
system("pause");
return 0;
}
结果:
相关文章推荐
- boost::unordered_map 和 std::map 的效率 与 内存比较
- 比较测试map、unodered_map、unordered_set性能效率,整型数值查找
- 使用类/结构体作为boost::unordered_map中的key时需要实现hash_value函数
- boost::array与std::vector使用与性能
- Boost::Array与Std::Vector使用与性能
- boost中的unordered_map使用方法
- boost::unordered_map 和 std::map 的对比(包括速度和内存消耗)
- C++11中std::unordered_map的使用
- C++11中std::unordered_map的使用
- STL:map和BOOST:unordered_map 实现简单比较
- std::map std::unordered_map 性能测试
- 几种智能指针的比较(std::auto_ptr、boost::scoped_ptr、boost::shared_ptr、boost::weak_ptr)
- 一次C#和C++的实际应用性能比较(C++允许我们使用任何手段来提高效率,只要愿意做出足够的努力)
- c++性能之map实现性能比较
- C++ std::unordered_map
- LinkedHashMap和HashMap的比较使用 详解
- MySQL性能测试工具之mysqlslap使用详解
- JAVA通过XPath解析XML性能比较详解
- Boost::bind使用详解
- hash_map,unordered_map的使用