是否有一个C ++ 11 strncmp替代品也可以执行?

时间:2015-11-01 19:33:36

标签: c++ c++11

我想在字符串中查找前缀。我一直在用这个:

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,但结果并不好。

2 个答案:

答案 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个字符,则没有未定义的行为:)