性能标准::strstr vs. 标准::字符串::查找

Performance std::strstr vs. std::string::find

本文关键字:标准 查找 字符串 strstr 性能 vs      更新时间:2023-10-16

可能的重复项:
C++字符串::查找复杂性

最近我注意到函数std::string::find比函数std::strstr慢一个数量级 - 在我的 Linux 上使用 GCC 4.7 的环境中。性能差异取决于字符串的长度和硬件体系结构。

造成这种差异似乎有一个简单的原因:std::string::find基本上是在循环中调用std::memcmp - 具有时间复杂度O(m * n) 。相比之下,std::strstr针对硬件架构进行了高度优化(例如,使用SSE指令),并使用更复杂的字符串匹配算法(显然是Knuth-Morris-Pratt)。

我也很惊讶没有在语言文档(即草案N3290和N1570)中发现这两个功能的时间复杂性。我只发现char_traits的时间复杂。但这无济于事,因为 char_traits 中没有子字符串搜索功能。

我希望std::strstrmemmem包含具有几乎相同性能的类似优化。直到最近,我还认为std::string::find内部使用memmem

问题是:有什么充分的理由,为什么std::string::find不使用std::memmem?它在其他实现中有什么不同吗?

问题不在于:这个函数的最佳实现是什么?如果它比 C 慢,那么C++真的很难争论。如果两个实现都很慢,我就没关系了。真正令人痛心的是性能差异。

首先,什么是memmem? 我在C++标准中找不到这个,也找不到Posix 标准(包含所有标准 C 函数)。

其次,任何测量值都将取决于实际数据。 用例如,在很多情况下,KMP 将是一种悲观;可能大多数情况下使用std::string的成员函数;设置必要表的时间通常超过直线算法的总时间。 像O(m*n)这样的事情当字符串的典型长度较短时,没有多大意义。