为什么我的性能基准给我错误的结果?

问题描述 投票:0回答:1

[clang-tidy选项performance-faster-string-find使用单个字符串文字作为参数来检测performance-faster-string-find方法(及相关方法)的使用。根据他们的说法,使用字符文字会更有效。

我想进行一些基准测试以进行测试。因此,我编写了这个小程序:

std::basic_string::find

此程序中使用了两个宏:

  • #include <string> #include <chrono> #include <iostream> int main() { int res = 0; std::string s(STRING_LITERAL); auto start = std::chrono::steady_clock::now(); for(int i = 0; i < 10000000; i++) { #ifdef CHAR_TEST res += s.find('A'); #else res += s.find("A"); #endif } auto end = std::chrono::steady_clock::now(); std::chrono::duration<double> elapsed_seconds = end-start; std::cout << "elapsed time: " << elapsed_seconds.count() << "s\n"; return res; } ,将是我们将在其上调用STRING_LITERAL函数的std::string的内容。根据我的基准,此宏可以有两个值:一个小字符串,例如find,或一个长字符串,例如"BAB"
  • "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",如果已定义,请运行字符文字基准测试。如果不是,则使用单个字符串文字调用CHAR_TEST

以下是结果:

find

我相当丑陋的命令为宏的四种可能组合运行了基准,我发现在> (echo "char with small string" ; g++ -DSTRING_LITERAL=\"BAB\" -DCHAR_TEST -O3 -o toy_exe toy.cpp && ./toy_exe) ; (echo "string literal with small string" ; g++ -DSTRING_LITERAL=\"BAB\" -O3 -o toy_exe toy.cpp && ./toy_exe) ; (echo "char with long string" ; g++ -DSTRING_LITERAL=\"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\" -DCHAR_TEST -O3 -o toy_exe toy.cpp && ./toy_exe) ; (echo "string literal with long string" ; g++ -DSTRING_LITERAL=\"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\" -O3 -o toy_exe toy.cpp && ./toy_exe) char with small string elapsed time: 0.0551678s string literal with small string elapsed time: 0.0493302s char with long string elapsed time: 0.0599704s string literal with long string elapsed time: 0.188888s 较长的情况下,使用字符文字作为std::string的参数确实更有效,但不再适用小find。我重复了实验,发现std::string较小的字符文字总是会增加大约10%的执行时间。

同时,我的一位同事在std::string上进行了一些基准测试,发现以下quick-bench.com

  • 带有字符文字的小results:11个时间单位
  • 具有单个字符串文字的小std::string:20个时间单位
  • 带有字符文字的长std::string:13个时间单位
  • 具有单个字符串文字的长std::string:22个时间单位

这些结果与主张整洁的观点相一致(听起来合乎逻辑)。那么,我的基准测试出了什么问题?为什么我总是出现错误的结果?


EDIT:此基准测试是在Debian上使用GCC 6.3.0执行的。我也使用Clang 8.0.0运行了它,以获得相似的结果。

c++ stdstring microbenchmark
1个回答
0
投票

我不确定您的基准标记是否有问题。我在repl.io平台上运行了完全相同的代码,并且得到了与“快速工作台”匹配的结果:

charsmall字符串。经过时间:0.402103s

string文字,带small字符串经过的时间:0.489828s

char,其中long字符串经过的时间:0.400224s

string文字,其字符串经过时间为[[long:0.53304s

想到的一件事,您的概要分析是在循环中完成的,我将简要介绍循环中的内容。
© www.soinside.com 2019 - 2024. All rights reserved.