哈希<std::string> 与哈希<std::string_view>

Posted

技术标签:

【中文标题】哈希<std::string> 与哈希<std::string_view>【英文标题】:hash<std::string> vs hash<std::string_view> 【发布时间】:2019-03-21 16:53:02 【问题描述】:

C++17 引入了hash&lt;string_view&gt;。在编写自己的自定义哈希时,我想重用字符串哈希的 STL 实现。

std::hash&lt;std::string&gt;()("Hello, world") 是否比 std::hash&lt;std::string_view&gt;()("Hello, world") 慢?是一样的吗?

我什么时候想使用std::hash&lt;std::string&gt;()

【问题讨论】:

【参考方案1】:

std::hash&lt;std::string&gt;()("Hello, world")std::hash&lt;std::string_view&gt;()("Hello, world") 慢吗?

是的。

前者较慢,因为创建std::string 比创建std::string_view 慢。

我什么时候想使用std::hash&lt;std::string&gt;()

当你有一个std::string 对象并且你想从中计算一个哈希值时。

【讨论】:

在第二种情况下我为什么不使用std::hash&lt;std::string_view&gt;()(myStr.c_str()) @Valentin 因为这是不必要的,更复杂,而且可能更慢。 @Valentin std::hash&lt;std::string&gt; 在散列文字时比较慢,因为必须制作字符串的副本。散列 std::string 时不会变慢。 @Valentin:一般来说,您通常不会直接要求哈希。您通常使用像unordered_map 这样的容器,它本身会要求哈希值。如果您需要unordered_map&lt;string, T&gt;,因为它需要拥有密钥的存储空间,那么它将使用hash&lt;string&gt; 而不是string_view 出于好奇,理论上是否允许编译器在此处传递字符串文字时在std::string 场景中应用堆省略?【参考方案2】:

std::hash&lt;std::string&gt;std::string const&amp; 作为其operator() 的参数。如果您有std::string,并且您正在对它们进行哈希处理,那么这就是您想要的。如果您使用hash&lt;string_view&gt;,则必须将std::string 转换为std::string_view,这需要花费一些成本(不多,但确实存在)。

如果您的数据集不仅包含 std::strings,还包含 c 字符串,那么 hash&lt;string_view&gt; 可能会更好。将 c 字符串转换为 std::string 可能需要动态内存分配,因此如果您可以避免这种情况,通常您会在性能领域获胜。这需要分析,因为 std::strings 和 c-strings 的混合以及 c-strings 的大小作为 SSO(短字符串优化)可能使 std::hash&lt;std::string&gt; 成为更好的选择。

【讨论】:

我更喜欢这个答案。 @eerorika 说“前者更慢,因为创建 std::string 比创建 std::string_view 慢”,我不明白为什么计算 std::string 的哈希意味着复制它 - 它只是通过如您所说,引用并对其进行操作。 @Valentin 请注意,eerorika 是正确的,std::hash&lt;std::string&gt;()("Hello, world")std::hash&lt;std::string_view&gt;()("Hello, world") 慢,因为它必须首先创建一个 std::string

以上是关于哈希<std::string> 与哈希<std::string_view>的主要内容,如果未能解决你的问题,请参考以下文章

如何将CString和:: std :: string :: std :: wstring互相转换?

使用 Crypto++ 生成 SHA256 哈希,使用字符串作为输入和输出?

C++ 引用踩的坑

C++ 引用踩的坑

手撸golang 基本数据结构与算法 哈希表

哈希是好东西,二分+哈希是更好的东西