哈希<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<string_view>
。在编写自己的自定义哈希时,我想重用字符串哈希的 STL 实现。
std::hash<std::string>()("Hello, world")
是否比 std::hash<std::string_view>()("Hello, world")
慢?是一样的吗?
我什么时候想使用std::hash<std::string>()
?
【问题讨论】:
【参考方案1】:
std::hash<std::string>()("Hello, world")
比std::hash<std::string_view>()("Hello, world")
慢吗?
是的。
前者较慢,因为创建std::string
比创建std::string_view
慢。
我什么时候想使用
std::hash<std::string>()
?
当你有一个std::string
对象并且你想从中计算一个哈希值时。
【讨论】:
在第二种情况下我为什么不使用std::hash<std::string_view>()(myStr.c_str())
?
@Valentin 因为这是不必要的,更复杂,而且可能更慢。
@Valentin std::hash<std::string>
在散列文字时比较慢,因为必须制作字符串的副本。散列 std::string
时不会变慢。
@Valentin:一般来说,您通常不会直接要求哈希。您通常使用像unordered_map
这样的容器,它本身会要求哈希值。如果您需要unordered_map<string, T>
,因为它需要拥有密钥的存储空间,那么它将使用hash<string>
而不是string_view
。
出于好奇,理论上是否允许编译器在此处传递字符串文字时在std::string
场景中应用堆省略?【参考方案2】:
std::hash<std::string>
将std::string const&
作为其operator()
的参数。如果您有std::string
,并且您正在对它们进行哈希处理,那么这就是您想要的。如果您使用hash<string_view>
,则必须将std::string
转换为std::string_view
,这需要花费一些成本(不多,但确实存在)。
如果您的数据集不仅包含 std::string
s,还包含 c 字符串,那么 hash<string_view>
可能会更好。将 c 字符串转换为 std::string
可能需要动态内存分配,因此如果您可以避免这种情况,通常您会在性能领域获胜。这需要分析,因为 std::string
s 和 c-strings 的混合以及 c-strings 的大小作为 SSO(短字符串优化)可能使 std::hash<std::string>
成为更好的选择。
【讨论】:
我更喜欢这个答案。 @eerorika 说“前者更慢,因为创建 std::string 比创建 std::string_view 慢”,我不明白为什么计算 std::string 的哈希意味着复制它 - 它只是通过如您所说,引用并对其进行操作。 @Valentin 请注意,eerorika 是正确的,std::hash<std::string>()("Hello, world")
比 std::hash<std::string_view>()("Hello, world")
慢,因为它必须首先创建一个 std::string
。以上是关于哈希<std::string> 与哈希<std::string_view>的主要内容,如果未能解决你的问题,请参考以下文章
如何将CString和:: std :: string :: std :: wstring互相转换?