关于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:感觉很详细,博主的其他内容也值得 ...
随机推荐
- Linux-Samba服务
Samba服务 1.Samba的起源 对于windows的网上邻居来讲,共享文件的方式用的是SMB和CIFS协议以及NETBIOS协议Linux/Unix之间用的是NFS协议. 但是Linux和Win ...
- 100、nginx_https安全链接配置
100.1. tcp的三次握手和四次挥手的过程: 1.三次握手(建立连接): 第一次:建立连接时,客户端发送SYN包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认: 第二次:服务器 ...
- layui table 使用table放输入框时控制每列的宽度
<table class="layui-table" lay-filter="demo"> <colgroup> <%--设置每列 ...
- AcWing 1290. 越狱
监狱有连续编号为1~n的n个房间,每个房间关押一个犯人.有 M种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人信仰的宗教相同,就可能发生越狱.求有多少种状态可能发生越狱. #include< ...
- SpringBoot | 1.1 SpringBoot简介
前言 本博客仅为记录与总结SpringBoot的学习笔记,资料来源: 书籍<深入浅出SpringBoot>第三版 B站尚硅谷<雷丰阳2021版SpringBoot2零基础入门> ...
- SpringBoot:WebSocket使用Service层的方法
方法一: 创建工具类 ApplicationContextRegister.java import org.springframework.beans.BeansException; import o ...
- Java:Java的~取反运算符详解
例: ~15 先变成二进制:15:0000 1111 这个其实挺简单的,就是把1变0,0变1 注意:二进制中,最高位是符号位 1表示负数,0表示正数
- java swagger ui 添加header请求头参数
我用到的swagger 主要有三款产品,swagger editor,swagger ui 和swagger codegen. swagger editor:主要是一个本地客户端,用来自己添加api, ...
- rename 批量修改文件名
1.rename的用法 rename与mv的区别就是mv只能对单个文件重命名,而rename可以批量修改文件名 linux中的rename有两种版本,一种是C语言版的,一种是Perl版的.早期的Lin ...
- Java笔记——方法
1.方法 (1)概念:①解决事情的办法②实现功能的代码段. (2)优点:①提到代码的复用性②便于后期维护. (3)特点:①不调用不执行②方法不能嵌套,定义在类中方法外的位置. (4)定义方 ...