Benchmark C `std::isdigit`

Viewed 125

I am trying to benchmark the function std::isdigit from the header cctype (the one inherited from C, just to be clear).

The code snippet is the following:

void BM_IsDigit_C(::benchmark::State& state) {
  const char c = GenerateRandomChar();
  for (auto _ : state) {
    ::benchmark::DoNotOptimize(std::isdigit(static_cast<unsigned char>(c)));
  }
}
BENCHMARK(BM_IsDigit_C);

It's quite easy to deduct that GenerateRandomChar is a simple function which generates a random char and should bring no overhead into the benchmark itself.


"""Unfortunately""", the compiler is able to completely optimize the code. It correctly generates the expected code for std::isdigit, but, in the assembly code of the benchmark the basic block is ignored.

The following is the profiled generated code (by gcc-10.1.0):

Perf Report

As you can see, the std::isdigit code is generated (compiler explorer example):

movzbl %r13b,%eax 
sub    $0x30,%eax
cmp    $0x9,%eax
setbe  %al     
movzbl %al,%eax

But it is completely ignored because of the empty loop:

68: sub    $0x1,%rbx   <---|
    jne    68        ------|

Little Note

The "C++ version" (with locale) generates the expected code: the loop testing the function code.

Perf Code C++


My questions are:

  • Why benchmark::DoNotOptimize does not work with this particular function?
  • How could I change the benchmark code in order to properly measure the time performance of that function?
Final Notes
  • I got the same "problem" with clang compiler.
  • I tried to "move" the tested function into another translation unit (forcing the not-inline attribute), but I got the same "problem".
0 Answers
Related