关于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:感觉很详细,博主的其他内容也值得 ...
随机推荐
- 6、inotify实时备份
备份用户nfs共享文件系统,存储单点解决方案inotify+rsync(增量,无差异备份),inotify是单线程, inotify是一种强大的,细粒度的,异步的文件系统事件监控机制,通过加入了ino ...
- centos Gitlab AD 集成
简述 Gitlab支持集成LDAP用户认证系统.兼容包括Microsoft Active Directory, Apple Open Directory, Open LDAP, 与389 Server ...
- Python 删除满足条件的某些行
数据: data 字段:col 要删除的内容是 col == False 的行 # 方案一 data1 = data[~data['col'] == False] # ~ 取反 # 方案二 保留 da ...
- buu firmware
一.路由器固件,给的是bin文件,要用binwalk将固件文件系统提取出来,同时binwalk的版本要完整不然解压不了文件,下面说的很清楚了. https://blog.csdn.net/QQ1084 ...
- FreeRTOS-00-基础知识+任务创建删除
1 说明 本文仅作为学习FreeRTOS的记录文档,作为初学者肯定很多理解不对甚至错误的地方,望网友指正. 1.1 简介 FreeRTOS是一个RTOS(实时操作系统)系统,支持抢占式.合作式和时间片 ...
- Python使用笔记20--网络操作小练习
1 ''' 2 2.自己抓取qq群的接口,传入一个群号,然后把群成员的头像下载到本地,头像用群备注来命名,如果没有 3 群备注,那么取昵称. 4 ''' 5 import requests 6 imp ...
- BiPredicate的test()方法
/** * BiPredicate的test()方法接受两个参数,x和y,具体实现为x.equals(y), * 满足Lambda参数列表中的第一个参数是实例方法的参数调用者,而第二个参数是实例方法的 ...
- Function.identity()
Java 8允许在接口中加入具体方法.接口中的具体方法有两种,default方法和static方法,identity()就是Function接口的一个静态方法.Function.identity()返 ...
- Day3 变量 运算符 及运算符的优先级
变量 什么是变量: 可以变化的量 Java 是一种强类型语言,每个变量都必须声明其类型. Java变量是程序中最基本的存储单位,其要素包括变量名,变量类型,作用域. 注意事项: 每个变量都有类型, 类 ...
- 前端开发入门到进阶第五集【安装SublimeServer】
参考:https://www.cnblogs.com/jf-67/p/8031614.html 1.我们可以直接在sublime text里面安装,Ctrl+shift+p进入命令模式,输入insta ...