关于c++ STL map 和 unordered_map 的效率的对比测试
本文采用在随机读取和插入的情况下测试map和unordered_map的效率
笔者的电脑是台渣机,现给出配置信息
处理器 : Intel Pentium(R) CPU G850 @ 2.90GHz × 2
内存 : 7.7GiB
操作系统 : Ubuntu 20.04.2 LTS 64位(Noi Linux 2.0)
由于在数据量小的情况下二者时间差异微乎其微,测试范围从1e4开始到1e7,map unordered_map存储为 int, int二元组,int三元组
单 int测试
| 插入范围 | 查询范围 | map插入时间 | map查询时间 | unordered_map插入时间 | unordered_map查询时间 |
|---|---|---|---|---|---|
| 10000 | 10000 | 11.95ms | 10.268ms | 15.184ms | 5.009ms |
| 100000 | 100000 | 113.374ms | 134.365ms | 200.852ms | 79.029ms |
| 1000000 | 1000000 | 1606.66ms | 1819.2ms | 2603.46ms | 862.877ms |
| 10000000 | 10000000 | 21688.5ms | 25461.7ms | 33973.7ms | 9484.45ms |
#include <bits/stdc++.h>
using namespace std;
int main()
{
for(int n = 1e4, m = 1e4; n <= 1e9, m <= 1e9; n *= 10,m *= 10)
{
cout << n << "|" << m ;
srand(n);
int t0 = clock();
map <int ,int> M;
for(int i = 1; i <= n; i++)
{
M[rand()] = i;
}
cout << "| " << (double)(clock() - t0) / 1000 << "ms ";
unsigned sum = 0;
t0 = clock();
for(int i = 1; i <= m; i++)
{
sum += M[rand()];
}
cout << "| " << (double)(clock() - t0) / 1000 << "ms ";
srand(n);
unordered_map <int, int> U;
for(int i = 1; i <= n; i++)
{
U[rand()] = i;
}
cout << "| " << (double)(clock() - t0) / 1000 << "ms ";
sum = 0;
t0 = clock();
for(int i = 1; i <= m; i++)
{
sum += U[rand()];
}
cout << "| " << (double)(clock() - t0) / 1000 << "ms |" << endl;
}
return 0;
}
二元组测试
| 插入范围 | 查询范围 | map插入时间 | map查询时间 | unordered_map插入时间 | unordered_map查询时间 |
|---|---|---|---|---|---|
| 10000 | 10000 | 10.617ms | 11.523ms | 16.301ms | 5.14ms |
| 100000 | 100000 | 122.489ms | 141.413ms | 195.278ms | 70.122ms |
| 1000000 | 1000000 | 1792.69ms | 2173.48ms | 2879.21ms | 783.437ms |
| 10000000 | 10000000 | 25017.8ms | 28777.1ms | 36499.8ms | 8666.73ms |
#include <bits/stdc++.h>
using namespace std;
struct PII
{
int x, y;
bool operator ==(const PII b) const
{
return x == b.x && y == b.y;
}
bool operator <(const PII b) const
{
return x != b.x ? x < b.x : y < b.y;
}
};
struct hashPII
{
size_t operator()(const PII &p) const
{
return hash<int>()(p.x) ^ hash<int>()(p.y);
}
};
int main()
{
for(int n = 1e4, m = 1e4; n <= 1e9, m <= 1e9; n *= 10,m *= 10)
{
cout << n << "|" << m ;
srand(n);
int t0 = clock();
map <PII ,int> M;
for(int i = 1; i <= n; i++)
{
M[{rand(), rand()}] = i;
}
cout << "| " << (double)(clock() - t0) / 1000 << "ms ";
unsigned sum = 0;
t0 = clock();
for(int i = 1; i <= m; i++)
{
sum += M[{rand(), rand()}];
}
cout << "| " << (double)(clock() - t0) / 1000 << "ms ";
srand(n);
unordered_map <PII, int, hashPII> U;
for(int i = 1; i <= n; i++)
{
U[{rand(), rand()}] = i;
}
cout << "| " << (double)(clock() - t0) / 1000 << "ms ";
sum = 0;
t0 = clock();
for(int i = 1; i <= m; i++)
{
sum += U[{rand(), rand()}];
}
cout << "| " << (double)(clock() - t0) / 1000 << "ms |" << endl;
}
return 0;
}
三元组测试
| 插入范围 | 查询范围 | map插入时间 | map查询时间 | unordered_map插入时间 | unordered_map查询时间 |
|---|---|---|---|---|---|
| 10000 | 10000 | 9.265ms | 10.061ms | 14.415ms | 4.325ms |
| 100000 | 100000 | 127.82ms | 141.59ms | 196.931ms | 70.29ms |
| 1000000 | 1000000 | 1700.73ms | 1971.21ms | 2685.96ms | 782.957ms |
O2
单 int测试
| 插入范围 | 查询范围 | map插入时间 | map查询时间 | unordered_map插入时间 | unordered_map查询时间 |
|---|---|---|---|---|---|
| 10000 | 10000 | 2.103ms | 2.617ms | 3.775ms | 1.261ms |
| 100000 | 100000 | 46.243ms | 67.461ms | 86.591ms | 34.024ms |
| 1000000 | 1000000 | 822.828ms | 1056.85ms | 1412.39ms | 422.122ms |
| 10000000 | 10000000 | 13690.2ms | 16854.1ms | 20994.4ms | 4903.84ms |
二元组测试
| 插入范围 | 查询范围 | map插入时间 | map查询时间 | unordered_map插入时间 | unordered_map查询时间 |
|---|---|---|---|---|---|
| 10000 | 10000 | 2.463ms | 3.461ms | 4.908ms | 2.209ms |
| 100000 | 100000 | 61.531ms | 89.114ms | 127.359ms | 49.821ms |
| 1000000 | 1000000 | 1301.74ms | 1692.79ms | 2184.67ms | 585.508ms |
| 10000000 | 10000000 | 21245.7ms | 24632.5ms | 30906.3ms | 7312.4ms |
理论复杂度
| map<int, int> | unordered_map<int, int> | ||
|---|---|---|---|
| 插入 | \(O(log( n ) )\) | \(O(log(n / m)\) m = 桶数 | |
| 读取 | \(O(log( n ) )\) | \(O(1) ?\) |
可以发现随着数据量的增大unordered_map在插入上由于冲突,性能是不及map的插入\(O(logn)\)的,但是其优秀的\(O(1) ?\)读取具有很大的性能优势
关于c++ STL map 和 unordered_map 的效率的对比测试的更多相关文章
- STL——map/unordered_map基础用法
map /multimap map是STL里重要容器之一. 它的特性总结来讲就是:所有元素都会根据元素的键值key自动排序(也可根据自定义的仿函数进行自定义排序),其中的每个元素都是<key, ...
- STL中的map、unordered_map、hash_map
转自https://blog.csdn.net/liumou111/article/details/49252645 在之前使用STL时,经常混淆的几个数据结构,特别是做Leetcode的题目时,对于 ...
- (转载)STL map与Boost unordered_map的比较
原链接:传送门 今天看到 boost::unordered_map,它与 stl::map的区别就是,stl::map是按照operator<比较判断元素是否相同,以及比较元素的大小,然后选择合 ...
- STL中的map和unordered_map
STL中的map和unordered_map map 头文件:#include 原理:std::map的内部实现了一颗红黑树,有对其键值进行排序的功能,所以map是一个有序的容器,map中的每一个元素 ...
- STL ——map、set、unordered_map、unordered_set
1.map和set map和set底层实现均是红黑树 map支持下标操作,set不支持下标操作. set的迭代器是const的,不允许修改元素的值:map允许修改value,但不允许修改key. se ...
- map 与 unordered_map
两者效率对比: #include <iostream> #include <string> #include <map> #include <unordere ...
- STL MAP及字典树在关键字统计中的性能分析
转载请注明出处:http://blog.csdn.net/mxway/article/details/21321541 在搜索引擎在通常会对关键字出现的次数进行统计,这篇文章分析下使用C++ STL中 ...
- STL map 用法
首先make_pair Pairs C++标准程序库中凡是"必须返回两个值"的函数, 也都会利用pair对象 class pair可以将两个值视为一个单元.容器类别map和mul ...
- STL map详细用法和make_pair函数
今天练习华为上机测试题,遇到了map的用法,看来博客http://blog.csdn.net/sprintfwater/article/details/8765034:感觉很详细,博主的其他内容也值得 ...
随机推荐
- UVA 11475 Extend to Palindrome hash
题意: 给出一个字符串,让你往后添加最少的字符,使其成为回文串. 分析: 题目就相当于求后缀字符串为回文串的最长长度,判断回文串要O(n)时间,直接判断肯定不行.我们从后往前枚举,每次字符串与上一个字 ...
- 4.3Unicode和ASCII码
- AcWing 241. 楼兰图腾
#include<bits/stdc++.h> using namespace std; const int N=2e5+5; typedef long long ll; ll ans,l ...
- Docker:docker搭建redis一主多从集群(配置哨兵模式)
角色 实例IP 实例端口 宿主机IP 宿主机端口 master 172.19.0.2 6382 192.168.1.200 6382 slave01 172.19.0.3 6383 192.168.1 ...
- Spring:Spring中bean的生命周期
Spring中,从BeanFactory或ApplicationContext取得的实例为Singleton(单例模式),就是预设为每一个Bean的别名只能维持一个实例,而不是每次都产生一个新的对象使 ...
- 关于Feign的Fallback处理
Feign的不恰当的fallback Feign的坑不少,特别与Hystrix集成之后. 在微服务引入Feign后,上线不久后便发现,对于一个简单的查询类调用,在下游返回正常的"404-资源 ...
- gitlab找回管理员密码
1.登陆后台服务器,切换git用户 su - git 2.登录GitLab的Rails控制台 gitlab-rails console production 另一种 切换root账户 执行: git ...
- 12 shell case in语句
Shell也支持两种分支结构(选择结构),分别是 if else 语句和 case in 语句.当分支较多,并且判断条件比较简单时,使用 case in 语句就比较方便了. if else 语句与ca ...
- C语言:scanf()
#include <stdio.h> int main() { int a;float b; scanf("a=%d,b=%f",&a,&b); pri ...
- Python多线程爬取某网站表情包
# 爬取网络图片import requestsfrom lxml import etreefrom urllib import requestfrom queue import Queue # 导入队 ...