dimanche 1 novembre 2015

Is there a C++11 strncmp alternative that performs as well? [on hold]

I want to look for a prefix in a string. I have been using this:

if (s.substr (0, 7) == "prefix_")
  ...

While this works, it is relatively slower than strncmp, as shown by this test:

#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;
}

I am seeing this performance, which surprised me:

[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

I would prefer to use C++11, without dropping back to libc, but the results are not good.

Aucun commentaire:

Enregistrer un commentaire