有没有办法在插入std :: unordered_multimap时避免散列/相等检查?

问题描述 投票:2回答:1

我使用std::unordered_multimap mymap作为我的数据结构,用于保存和快速访问类型为T的超过10M元素(~10GB数据)作为自定义和不可避免的昂贵散列和相等(operator==)函数的关键。

问题是它比我所熟悉的(大约45分钟左右)将所有数据集加载并存储到mymap中需要更长的时间,因为在数据存储后它不会改变我决定迭代桶并写将它们的元素分成单独的文件(序列化),以便下次我只创建足够的桶,保留内存,并直接将它们放在它们的位置(反序列化)并避免散列和相等性检查。

这将大大减少加载时间。 (低至约60秒)

遗憾的是,我找不到将元素直接插入std::unordered_multimap的底层数据结构并绕过hashing / equalityChecking的方法。

更新:

  • 事实证明我的哈希算法中存在一个错误,导致我的元素仅在几个桶中堆积,我修复了这个错误,然后只需81秒就可以将数据集加载到地图中。 (从约45分钟开始)
  • 正如@aconcagua建议的那样,我尝试将预计算哈希值用于我的数据类型,并将加载时间减少到79秒。所以看起来我的哈希算法毕竟不是那么昂贵,而且我已经尽力确保我的相等函数在每次操作时都得到了优化,但我认为它并没有变得更快。我应该研究编写自己的哈希映射。
c++ c++-standard-library
1个回答
2
投票

std::unordered_map不提供这样的功能,你会依赖脏兮兮的黑客。因此,您可以编写自己的哈希映射以允许此类操作 - 或者您可以按如下方式重新计算哈希计算所花费的时间:

class C
{
    size_t m_hashCode;
    bool m_isHashDirty;

public:
    C() : m_isHashDirty(true);

    size_t hashCode()
    {
        if(m_isHashDirty)
        {
             m_hashCode = /* result of complex calculations */;
        }
        return m_hashCode;
    }
};

对象的任何修改都会设置脏标志,但您只能根据需要计算哈希值,并且如果之前的调用有更改。

您当然会在序列化时存储哈希码,并在反序列化时将其还原,将脏标志设置为false。

Equality运算符提供更少的优化选项,当然您可以在第一个检测到的不同成员上快捷键结果,但在最后一个成员检查之前,相等性不会确定。所以你可能宁愿改进你的哈希函数以产生更少的冲突。

© www.soinside.com 2019 - 2024. All rights reserved.