【问题标题】:unordered_map with forbidden collisionsunordered_map 禁止碰撞
【发布时间】:2011-04-11 14:24:45
【问题描述】:

我想实现一个性能优化的unordered_map 变体,它分几个阶段工作:

  1. 初始化:在std::map中插入大约100个元素
  2. 准备工作:做一些魔术,将std::map 转换为std::unordered_map 的变体
  3. 工作:执行大量(无限)查找;禁止插入/删除

为了使“工作”阶段尽可能快,我想为给定的一组键选择一个没有冲突的散列函数(在初始化阶段收集)。

我想衡量我可以从这个技巧中获得多少性能改进。所以这将是一个实验,可能会进入生产代码。

标准库是否有用于此实现的功能(例如,查找给定的 unordered_map 有多少冲突;或更改散列函数)?还是我应该自己实现?

【问题讨论】:

  • 看看 gperf 以生成完美的散列函数(当然,如果您希望散列完美,则需要将 所有 输入交给它... )
  • 我很确定 gperf 需要在编译时知道完整的项目集。
  • 使用完美散列等现有方法怎么样? en.wikipedia.org/wiki/Dynamic_perfect_hashing

标签: c++ optimization hash c++-standard-library


【解决方案1】:

这里是“碰撞管理”API:

size_type bucket_count() const;
size_type max_bucket_count() const;

size_type bucket_size(size_type n) const;
size_type bucket(const key_type& k) const;

local_iterator       begin(size_type n);
local_iterator       end(size_type n);
const_local_iterator begin(size_type n) const;
const_local_iterator end(size_type n) const;
const_local_iterator cbegin(size_type n) const;
const_local_iterator cend(size_type n) const;

简而言之,bucket_size(n) 为您提供第 n 个存储桶的碰撞次数。您可以使用键查找存储桶,也可以使用 local_iterator 遍历存储桶。

为了更改哈希函数,我将分配/构造一个新容器,从旧的哈希函数到新的。

【讨论】:

    【解决方案2】:

    如果您有很多读取和较少写入,您可以使用向量作为映射。这很常见,因为lower_boundmap 更有效,并且占用的内存空间更少:

    bool your_less_function( const your_type &a, const your_type &b )
    {
      // based on keys
      return ( a < b );
    }
    ...
    std::vector<your_type> ordered-vector;
    

    添加值时:

    ...
    // First 100 values
    ordered-vector.push_back(value)
    ...
    // Finally. The vector must be sorted before read.
    std::sort( ordered-vector.begin(), ordered-vector.end(), your_less_function );
    

    询问数据时:

    std::vector<your_type>::iterator iter = std::lower_bound( ordered-vector.begin(), ordered-vector.end(), value, your_less_function );
    if ( ( iter == ordered-vector.end() ) || your_less_function( *iter, value ) )
      // you did not find the value
    else
      // iter contains the value
    

    不幸的是,它是订购的,但真的很快。

    【讨论】:

    • 表中只有 100 个条目,在 lower_bound 中通过二分搜索完成的比较应该很快。不过,一个简单的哈希仍然可能更快。
    【解决方案3】:

    冲突的数量取决于桶的数量。根据boost documentation,使用 rehash 函数将桶数设置为 100 对您有用吗?

    【讨论】:

      猜你喜欢
      • 2013-06-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-01
      • 1970-01-01
      相关资源
      最近更新 更多