C++ 了解std::optional在不同平台上的性能差异

C++ 了解std::optional在不同平台上的性能差异,c++,performance,gcc,optional,C++,Performance,Gcc,Optional,我试图了解在接口设计中使用std::optional的开销,无论是对单个接口使用std::optional还是对“isNull和getX”组合使用,主要关注的是了解std::optional的开销。所以我制作了这个简单的程序来测试它 本文总结了代码片段和测试结果 令人惊讶的是,有两件事我不明白,我想从专家那里得到帮助 在使用gcc(8和9都经过测试)的linux平台上,我看到一致的std::optional优于直接条件,这是我不理解的 在Mac(我的笔记本电脑)上,我看到程序的执行速度比lin

我试图了解在接口设计中使用
std::optional
的开销,无论是对单个接口使用
std::optional
还是对“isNull和getX”组合使用,主要关注的是了解
std::optional
的开销。所以我制作了这个简单的程序来测试它

本文总结了代码片段和测试结果

令人惊讶的是,有两件事我不明白,我想从专家那里得到帮助

  • 在使用gcc(8和9都经过测试)的linux平台上,我看到一致的
    std::optional
    优于直接条件,这是我不理解的

  • 在Mac(我的笔记本电脑)上,我看到程序的执行速度比linux上测量的时间快(12毫秒vs>60毫秒),我不明白为什么会这样(是因为Apple LLVM impl吗?),从CPU信息来看,我不认为Mac更快,也许我错过了其他需要检查的信息

任何指点都将不胜感激

基本上理解这两个平台之间的运行时差异,可能与处理器相关,或者与编译器相关,我不确定。复制应用程序附在要点中。另外,我不太明白为什么
std::optional
在使用GCC的linux上更快

详见要点

代码片段(根据建议从要点复制)

Linux Ubuntu 18.04 LTS 36芯-其中一个 处理器:0 供应商id:GenuineIntel cpu系列:6 型号:85 型号名称:英特尔(R)至强(R)白金8124M处理器@3.00GHz 步进:4 微码:0x100014a cpu MHz:1685.329 缓存大小:25344KB 物理标识:0 兄弟姐妹:36 核心id:0 cpu核心数:18 apicid:0 初始apicid:0 fpu:是的 fpu_例外:是 cpuid级别:13 wp:是的 标志:fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse2 ss ht syscall nx pdpe1gb rdtscp lm常量tsc arch性能良好无拓扑不间断tsc cpuid aperfmperf tsc已知频率pni pclmulqdq监视器ssse3 fma cx16 pcid sse4 sse4 sse4 2 apic MOVTC tsc截止时间计时器aesavx f16c rdrand虚拟机监控程序lahf_lm abm 3DNOW预取invpcid_single pti fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm mpx avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves ida arat pku ospke

/usr/bin/g++--版本

g++(Ubuntu 9.1.0-2ubuntu2~18.04)9.1.0 版权所有(C)2019免费软件基金会 ====生成标志===== [为Mac创建命令捕获]

/usr/bin/g++-I/Users/shawncao/nebula/include-I/Users/shawncao/nebula/src-I/usr/local/ceral/boost/1.70.0/include-I/usr/local/ceral/folly/2019.08.05.00/include-I/Users/shawncao/nebuckoofilter/src/buckoofilter/src-I/Users/shawncao/nebuckoofilter/build/fmtproj/prefix/src/fmtproj/src/src/fmtproj/include-I/Users/Users/shawncao/uses/shawncao/src/src/sr-isystem/usr/local/include-isystem/Users/shawncao/nebula/build/gflagsp prefix/src/gflagsp build/include-isystem/Users/shawncao/nebula/glogp prefix/src/nebuld/rowingproj prefix/src/rowingproj/include-isystem/Users/shawncao/nebuild/nebuild/rowingproj/rowingproj prefix-isystem/用户/shawncao/nebula/build/yomm2前缀/src/yomm2/include-isystem/Users/shawncao/nebula/build/xxhash前缀/src/xxhash-isystem/Users/shawncao/nebula/build/bloom/src/bloom-isystem/usr/local/cillar/openssl/1.0.2s/include-Wall-Wextra-Werror-Wno错误=可空性完整性-Wno错误=符号比较-Wno错误=未知警告选项-O3-isysroot/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk-std=gnu++1z-o CMakeFiles/CommonTests.dir/src/common/test/TestExts.cpp.o-c/Users/shawnco/nebula/src/common/test/TestExts.cpp [100%]链接CXX可执行文件测试 /Applications/CMake.app/Contents/bin/CMake-E CMake_link_script CMakeFiles/CommonTests.dir/link.txt--verbose=1 /usr/bin/g++-Wall-Wextra-Werror-Wno error=nullability completure-Wno error=sign compare-Wno error=unknown warning option-O3-isysroot/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk-Wl,-首先搜索路径-Wl,-headerpad_max_install_name cmakfiles/CommonTests.dir/src/common/test/TestCommon.cpp.o cmakfiles/CommonTests.dir/src/common/test/TestExts.cpp.o-o CommonTests-Wl,-rpath,/Users/shawncao/nebula/build/bloom/src/bloom build/libNCommon.a yomm2前缀/src/yomm2 build/src/libyomm2.a googletest前缀/src/googletest build/lib/libgtest.a googletest前缀/src/googletest build/lib/libgtest@main.a xxhash前缀/src/xxhash/libxxhash.a roringproj前缀/src/roringproj build/src/libroring.aglogp prefix/src/glogp build/libglog.a gflagsp prefix/src/gflagsp build/lib/libgflags.a bloom/src/bloom build/lib/libbf.dylib libcflib.a/usr/local/ceral/openssl/1.0.2s/lib/libssl.a fmtproj prefix/src/fmtproj build/libfmt.a

[build commands capture for Linux] /usr/bin/g++-Wall-Wextra-Werror-lstdc++-Wl,--no-as-need-no-pie-ldl-lunwind-I/usr/include/-I/usr/local/include-L/usr/local/lib-L/usr/lib-O3-s cmakfiles/CommonTests.dir/src/common/test/tests/TestCommon.cpp.o cmakfiles/dir/src/common/tests/common/tests.cpp.o-o CommonTests-Wl-rpath,/home/shawnco/nebula/build/bloom/src/bloom build/libNCommon.a yomm2前缀/src/yomm2 build/src/libyomm2.a/usr/local/libgtest.a/usr/local/libgtest_main.a xxhash前缀/src/xxhash/libxxhash.a roringproj前缀/src/roringproj build/src/libroring.a/usr/local/libglog/libgflags.a bloom/src/lib/lib/bf.solibcflib.a/usr/local/lib/l
inline bool f1ni(int i) {
  return i % 2 == 0;
}

TEST(OptionalTest, TestOptionalPerf) {
  auto f1 = [](int i) -> int {
    return i + 1;
  };

  auto f2 = [](int i) -> std::optional<int> {
    if (i % 2 == 0) {
      return {};
    }
    return i + 1;
  };

  // run 1M cycles
  constexpr auto cycles = 100000000;
  nebula::common::Evidence::Duration duration;
  long sum2 = 0;
  for (int i = 0; i < cycles; ++i) {
    auto x = f2(i);
    if (x) {
      sum2 += x.value();
    }
  }
  LOG(INFO) << fmt::format("optional approach: sum={0}, time={1}", sum2, duration.elapsedMs());

  duration.reset();
  long sum1 = 0;
  for (int i = 0; i < cycles; ++i) {
    if (i % 2 != 0) {
      sum1 += f1(i);
    }
  }
  LOG(INFO) << fmt::format("special value approach: sum={0}, time={1}", sum1, duration.elapsedMs());
  EXPECT_EQ(sum1, sum2);

[Test Output]
I0812 09:36:20.678683 348009920 TestCommon.cpp:354] optional approach: sum=2500000050000000, time=13
I0812 09:36:20.692001 348009920 TestCommon.cpp:363] special value approach: sum=2500000050000000, time=12
[Test Output]
I0812 16:42:07.391607 15080 TestCommon.cpp:354] optional approach: sum=2500000050000000, time=59
I0812 16:42:07.473335 15080 TestCommon.cpp:363] special value approach: sum=2500000050000000, time=81