最近我注意到函数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::strstr
和memmem
包含类似的优化,但性能几乎相同。直到最近,我才假设std::string::find
在内部使用memmem
。
问题是:有什么好的理由,为什么std::string::find
不使用std::memmem
?它在其他实现方面有所不同吗?
问题不是:这个功能的最佳实现是什么?如果它比C慢,那么对C ++来说真的很难说。如果两个实现都很慢,我就无所谓了。真正伤害的是性能差异。
答案 0 :(得分:2)
首先,memmem
是什么?我在C ++标准中找不到这个,也没有
Posix标准(包含所有标准C函数)。
其次,任何测量值都取决于实际数据。运用
例如,KMP在许多情况下将是一种悲观情绪;大概
大多数使用std::string
成员函数的情况;
设置必要表格的时间通常会超过
直接算法的总时间。像O(m*n)
这样的事情
当字符串的典型长度很短时,并不意味着什么。