map与unordered_map效率的比较

本文探讨了C++中map与unordered_map在插入和遍历效率上的对比。测试结果显示,在适当的桶数设置下,unordered_map在插入速度上始终优于map,尤其是在大量数据时。然而,map在遍历效率上略胜一筹。测试环境为g++ 4.4.6,未考虑rehash和计算素数的时间成本。

之前在某blog看到map在非常少量数据下插入效率高于unordered_map。

自己测了一下并非如此,在设置合适的桶数的情况下,有如下结论:

1、插入效率unordered_map任何情况下均优于map,数据越多越明显。

2、遍历效率map略优于unordered_map。

补充:

1、只在 g++ 4.4.6下测试,-o2与无编译器优化结果一致。

2、没有计算rehash与计算素数的时间,因为一般在程序启动时就rehash了,所以忽略掉。

直接上代码

#include <iostream>
#include <map>
#include <unordered_map>
#include <set>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
#include <unistd.h>
using namespace std;

/// 返回大于1.5 * num的第一个素数
inline size_t get_hash_table_size(unsigned int num) {
	size_t return_num = 1.5 * num, i, j;
	while (1) {
		/// 素数判断
		j = (size_t)sqrt(return_num++);
		for (i = 2; i < j; ++i) {
			if (return_num % i == 0)
				break;
		}
		if (i == j)
			return return_num;
	}
}

long get_time_usec_gap(const timeval &start, const timeval &end)
{
	return (end.tv_sec - start.tv_sec) * 1000000 + end.tv_usec - start.tv_usec;
}

int main()
{
	cout<<"please input map size: "<<endl;
	int map_size;
	cin>>map_size;

	if (map_size <= 0) {
		return -1;
	}

	set<int> random_nums_set;

	srand(time(0));
	for (int i = 0; i < map_size; ) {
		int random_nums = rand();
		if (0 == random_nums_set.count(random_nums)) {
			random_nums_set.insert(random_nums);
			++i;
		}
	}

	map<int, int> map_test;
	unordered_map<int, int> unordered_map_test;
	unordered_map_test.rehash(get_hash_table_size(map_size));

	struct timeval t_start,t_end;
	gettimeofday(&t_start, 0);
	for (auto it = random_nums_set.begin(); it != random_nums_set.end(); ++it) {
        map_test.insert(std::make_pair(*it, 0));
	}
	gettimeofday(&t_end, 0);
	cout<<"map insert time:"<<get_time_usec_gap(t_start, t_end)<<endl;

	gettimeofday(&t_start, 0);
	for (auto it = random_nums_set.begin(); it != random_nums_set.end(); ++it) {
        unordered_map_test.insert(std::make_pair(*it, 0));
		unordered_map_test[*it] = 100;
	}
	gettimeofday(&t_end, 0);

	cout<<"unordered_map insert time:"<<get_time_usec_gap(t_start, t_end)<<endl;

	gettimeofday(&t_start, 0);
	for (auto it = map_test.begin(); it != map_test.end(); ++it) {
	}
	gettimeofday(&t_end, 0);
	cout<<"map traverse time:"<<get_time_usec_gap(t_start, t_end)<<endl;

	gettimeofday(&t_start, 0);
	for (auto it = unordered_map_test.begin(); it != unordered_map_test.end(); ++it) {
	}
	gettimeofday(&t_end, 0);
	cout<<"unordered_map traverse time:"<<get_time_usec_gap(t_start, t_end)<<endl;

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值