当前位置: 代码迷 >> 综合 >> unordered_map 性能优化 与 重载
  详细解决方案

unordered_map 性能优化 与 重载

热度:16   发布时间:2024-01-09 10:41:14.0

参考: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)]);
}