我想在字符串中查找前缀。我一直在用这个:
if (s.substr (0, 7) == "prefix_")
...
虽然这有效,但它比strncmp
慢,如此测试所示:
#include <iostream>
#include <chrono>
#include <string>
#include <string.h>
int main ()
{
std::string s = "prefix_this is a passing test that will always match";
auto t0 = std::chrono::high_resolution_clock::now ();
for (int i = 0; i < 1000000; i++)
if (s.substr (0, 7) == "prefix_")
;
auto t1 = std::chrono::high_resolution_clock::now ();
for (int i = 0; i < 1000000; i++)
if (! s.compare (0, 7, "prefix_", 0, 7))
;
auto t2 = std::chrono::high_resolution_clock::now ();
for (int i = 0; i < 1000000; i++)
if (! strncmp (s.c_str (), "prefix_", 7))
;
auto t3 = std::chrono::high_resolution_clock::now ();
std::cout << "[1] s.substr (0, 7) == \"prefix_\" "
<< std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count()
<< " μs\n"
<< "[2] ! strncmp (s.c_str (), \"prefix_\", 7) "
<< std::chrono::duration_cast<std::chrono::microseconds>(t2 - t1).count()
<< " μs\n"
<< "[3] ! s.compare (0, 7, \"prefix_\", 0, 7) "
<< std::chrono::duration_cast<std::chrono::microseconds>(t3 - t2).count()
<< " μs\n";
return 0;
}
我看到这种表现让我感到惊讶:
[1] s.substr (0, 7) == "prefix_" 33022 μs
[2] ! strncmp (s.c_str (), "prefix_", 7) 32547 μs
[3] ! s.compare (0, 7, "prefix_", 0, 7) 12953 μs
我更喜欢使用C ++ 11,而不是回退到libc,但结果并不好。
答案 0 :(得分:12)
是强>
您可以使用以下内容来避免字符串构造,即实际类似于strncmp
:
if (s.compare(0, 7, "prefix_") == 0) {}
实际上,当然,我建议不要硬编码 n 值。
与往常一样,只需花费五分钟时间仔细阅读标准库参考goes a long way ...
答案 1 :(得分:1)
如果您可以使用强制(强制警告),您也可以将其写为
if(boost::string_ref(s).substr(0, 7) == "prefix_")
...
事实上,这是其介绍性示例之一。 Altenatively
if(boost::string_ref(s).starts_with("prefix_"))
...
后者是不同的,因为如果你的字符串实际上少于7个字符,则没有未定义的行为:)