unordered_map 性能优化 与 重载

参考:stl中unordered_map的insert/clear 性能问题解决
参考:关于map和unorderd_map的使用


insert / clear 性能优化

当插入元素过多时,发生了哈希碰撞,碰撞开链到一定的阈值,触发了增加 b u c k e t bucket bucket,进而触发了 r e h a s h rehash rehash

因此, r e s e r v e reserve reserve 可以用来预留元素个数, r e h a s h rehash rehash 根据提供的元素个数预留足够的bucket数目

unordered_map <int, int> mp;
mp.reserve(2e7);
mp.rehash(2e7); 

同时, u n o r d e r e d _ m a p unordered\_map unordered_map 每清空一次会遍历删除所有内容,可以替换为 s w a p swap swap

unordered_map <int, int> mp1;
mp.swap(mp1);

时间复杂度即可降为 O ( 1 ) O(1) O(1)


重载

u n o r d e r e d _ m a p unordered\_map unordered_map 是哈希表的机制,也就是每个 k e y key key 会生成一个哈希码,根据哈希码来判断元素是否相同,故必须提供产生哈希码的函数,但是哈希码相同并不一定代表两个元素相同,所以还要实现 = = == == 操作符。

以下用三种方式重写哈希:
①:手动重写
②:调用 b o o s t boost boost 库函数(要手动下载 b o o s t boost boost 库)
③:简单哈希

#include<bits/stdc++.h>
#define rint register int
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;

//#include <functional>
// from boost (functional/hash):
// see http://www.boost.org/doc/libs/1_35_0/doc/html/hash/combine.html template
template <typename T>
inline void hash_combine(std::size_t &seed, const T &val) {
    seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
// auxiliary generic functions to create a hash value using a seed
template <typename T> inline void hash_val(std::size_t &seed, const T &val) {
    hash_combine(seed, val);
}
template <typename T, typename... Types>
inline void hash_val(std::size_t &seed, const T &val, const Types &... args) {
    hash_combine(seed, val);
    hash_val(seed, args...);
}

template <typename... Types>
inline std::size_t hash_val(const Types &... args) {
    std::size_t seed = 0;
    hash_val(seed, args...);
    return seed;
}


struct node {
	string str;
	int num;
	node(string _str, int _num):str(_str), num(_num) {}
	bool operator == (const node &A) const {
		return (str==A.str && num==A.num);
	}
};
struct node_hash {
	size_t operator() (const node &A) const {
		return hash_val(A.str, A.num);	// 重写 
		
//	    using boost::hash_value;
//	    using boost::hash_combine;
//		size_t seed = 0;
//		hash_combine(seed, hash_value(A.str));
//		hash_combine(seed, hash_value(A.num));
//		return seed;	// 调用 
		
//		return hash<string>()(A.str) ^ hash<int>()(A.num);	// 简单 
	}
};
unordered_map <node, int, node_hash> mp;


signed main() {
	mp[node("wpf", 666)] = 11;
	mp[node("zzz", 123)] = 22;
	printf("%d\n", (*mp.begin()).first.num);
	printf("%d\n", (*mp.begin()).second);

	deb(mp[node("zzz", 123)]);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值