Unordered_map插入将停止
unordered_map insertion crawls to a halt
基本上,我有一个unordered_map并试图添加到它的配对集…大约有50万人。我注意到,当我添加对插入速度变得越来越慢,直到它最终停止在一起。有什么想法,为什么这可能是或如何解决这个问题?
地图定义:std::tr1::unordered_map<std::pair<int, int>, int, pairHash> x_map ;
哈希函数-注意,对于我的情况,我不必担心pair.first==pair。第二,所以我相信这个哈希函数应该是足够的,如果我错了请纠正我:
class pairHash
{
public:
size_t operator()(const std::pair<int, int> & v) const
{
return v.first ^ v.second ;
}
} ;
向unordered_map…尝试添加200,000-500,000对:
initialize_map( EndPoint**& arr, std::tr1::unordered_map<std::pair<int, int>, int, pairHash> &my_map, int size )
{
for( int i = 0 ; i < size ; i++ ) // add initial overlapping pairs
{
if( i % 100 == 0 )
std::cout << "checking particle: " << i << " maxsize: " << my_map.max_size() << std::endl ;
int j = 1 ;
while( arr[i]->isMin && i+j < size && // while ys is a min, and not end of array
arr[i]->v_id != arr[i+j]->v_id ) // anything between min and max is a possible collision
{
if( !arr[i]->isEdge || !arr[i+j]->isEdge )
{
my_map[std::make_pair( std::min( arr[i]->v_id, arr[i+j]->v_id ),
std::max( arr[i]->v_id, arr[i+j]->v_id ) )] = 1 ;
}
j++ ;
}
}
}
编辑:我实际上加了将近5000万双……刚刚做了个测试…
EDIT2:
冻结前的示例输出,其中count是映射中的条目数。我认为它正在尝试重新散列映射,但不确定为什么它没有这样做,并且冻结了计算机:
检粒:87500计数:35430415负载系数:0.988477
检粒:87600计数:35470808负载系数:0.989652
检粒:87700计数:35511049负荷系数:0.990818
检粒:87800计数:35555974负载系数:0.992073
检粒:87900计数:35595646负荷系数:0.993163
检粒:88000计数:35642165负荷系数:0.994427
检粒:88100计数:35679608负载系数:0.995434
检粒:88200计数:35721223负荷系数:0.996563
检粒:88300计数:35760313负载系数:0.997616
检粒:88400计数:35799621负载系数:0.9987
检查颗粒:88500计数:35833445负载系数:0.999649
为了获得更好的散列函数,最好还是坚持使用Boost hash_combine
解决方案:
template <class T>
inline void hash_combine(std::size_t & seed, const T & v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
namespace std
{
template<typename S, typename T> struct hash< std::pair<S, T> >
{
inline std::size_t operator()(const std::pair<S, T> & v) const
{
std::size_t seed = 0;
hash_combine(seed, v.first);
hash_combine(seed, v.second);
return seed;
}
};
}
试着看看unordered_map::load_factor()。这个调用的理想结果应该是<1.0. 如果它超过1.0,那么你的哈希函数可能是有问题的。您应该使用hash_combine而不是xor对。
您是否尝试使用reserve()
为所有对预分配足够的桶?添加这么多对可能会触发许多调整大小(和重新哈希)。
接下来我要检查的是你的哈希函数。这看起来有点可疑,如果你有很多哈希冲突,你可能会得到一堆溢出桶,这减慢了每次插入的查找速度——在这种情况下,你最好使用std::map
。您可以修改代码来存储每对的哈希值,然后检查生成的唯一哈希值的数量。
- 将重物插入std::map
- 为什么映射插入和 map.find() 的单次迭代比插入和 map.find() 的两次单独迭代慢得多
- 找不到最新插入到 std::map 中的键
- 在 std::map 中插入数组元素
- 插入 std::set 作为 std::map 的键
- 通过构造函数插入 std::map
- 将带有模板的自定义类插入到 std::map 中
- std::map 索引运算符与插入方法的性能
- 尝试在 std::map 中插入抽象类时没有用于调用的匹配函数
- 如何在声明时将对象插入 std::map
- 如何在 std::map<const int、int> C++ 中重载插入运算符>>?
- 在 std::map 中插入对象时构造函数中变量的地址
- 在这种情况下,插入 std::map 可能会失败?
- 从元组向 std::map 插入值
- 如何在 C++11 中插入 std::map?
- std::map::emplace无法解决,但插入右值有效 - 为什么?
- C++ 堆栈中的类对象作为 Map 的值插入
- 查找并插入-STD :: MAP C
- 将项目插入到std :: map时错误
- 将列表初始化的对插入到 std::map 中