c++ - unordered_map 插入爬行停止

标签 c++ hash hashmap unordered-map

基本上,我有一个 unordered_map 并试图向其中添加成对的集合……大约有 500,000 个。我注意到,当我添加对时,插入速度变得越来越慢,直到它最终完全停止。关于为什么会这样或如何解决这个问题有什么想法吗?

map 定义:

std::tr1::unordered_map<std::pair<int, int>, int, pairHash> x_map ;

哈希函数 - 请注意,对于我的情况,我不必担心 pair.first==pair.second,所以我相信这个哈希函数应该足够了,如果有误请纠正我:

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++ ;
        }
    }
}

编辑: 我实际上添加了近 50,000,000 对……刚刚进行了测试……

编辑2:

卡住前的示例输出,其中 count 是映射中的条目数。我相信它正在尝试重新散列 map ,但不确定为什么它没有这样做并卡住了计算机:

检查粒子: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;
    }
  };
}

关于c++ - unordered_map 插入爬行停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8030481/

相关文章:

java - 使用整数作为字符串对 HashMap<String, String> 进行排序

database - 尝试使用 DynamoDBMapper 时出现异常 : no mapping for HASH key

Python - 当识别出重复项时,集合或卡住集合采用哪个对象?

android - Square 的 Retrofit Android : Hash With Contents of Request

c++ - 如何从多个函数调用中抛出异常一直返回到 main?

java - 如何检查字符串是否为数字

java - 使用键升序排序arraylist

javascript - C# 使用 + 运算符的奇怪行为

c++ - 为什么创建一个由不同进程共享的环形缓冲区如此困难(在 C++ 中),我做错了什么?

c++ - 用于计算文件中字符串数量的预处理器