有没有一种方法可以避免在插入std :: unordered_multimap时进行哈希/ equalityChecking?

时间:2018-09-15 09:22:19

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

我正在使用std::unordered_multimap mymap作为我的数据结构,以保持和快速访问类型为T的超过10M个元素(〜10GBs数据)作为键,并具有自定义且不可避免的昂贵散列和等价作用({ {1}})功能。

问题在于,将所有数据集加载并存储到mymap中所需的时间比我所能接受的时间长(大约45分钟左右),并且由于在存储数据后它不会改变,因此我决定进行迭代存储桶并将其元素写入单独的文件中(序列化),因此下一次我将创建足够的存储桶,保留内存并直接将它们放在其位置(反序列化),并避免哈希和相等检查。

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

遗憾的是,我找不到一种将元素直接插入operator==的基础数据结构中并绕过哈希/ equalityChecking的方法。

更新:

  • 原来,我的哈希算法中存在一个错误,导致我的元素仅堆积在几个存储桶中,我对此进行了修复,然后仅用了81秒就将数据集加载到地图中。 (从〜45分钟开始)
  • 按照@aconcagua的建议,我尝试将预计算的哈希值用于我的数据类型,并将加载时间降低至79秒。因此,看来我的哈希算法毕竟并不算昂贵,而且我已尽力确保对每个操作优化我的相等函数,但我想它并没有得到更快的发展。我应该研究编写自己的哈希图。

1 个答案:

答案 0 :(得分: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;
    }
};

对对象的任何修改都会设置脏标志,但是只有在需要时以及上一次调用发生更改时,您才计算哈希。

您当然需要在序列化时存储哈希码,在反序列化时将其恢复,将dirty标志设置为false。

相等运算符提供较少的优化选项,您当然可以将第一个检测到的不同成员的结果捷径化,但是直到最后一个成员被选中时,才能确保相等。因此,您可能宁愿改进哈希函数以减少冲突。