#include #include #include #include #include #include Y_CPU_BENCHMARK(F, iface) { TVector x; x.reserve(iface.Iterations()); for (size_t i = 0; i < iface.Iterations(); ++i) { x.push_back(i); } } Y_CPU_BENCHMARK(EmptyF, iface) { (void)iface; } Y_CPU_BENCHMARK(AlmostEmptyF, iface) { (void)iface; TVector x; x.resize(1); } Y_CPU_BENCHMARK(TestThrow, iface) { for (size_t i = 0; i < iface.Iterations(); ++i) { try { ythrow yexception() << i; } catch (...) { //CurrentExceptionMessage(); } } } Y_CPU_BENCHMARK(TestThrowBT, iface) { for (size_t i = 0; i < iface.Iterations(); ++i) { try { ythrow TWithBackTrace() << i; } catch (...) { //CurrentExceptionMessage(); } } } Y_CPU_BENCHMARK(TestThrowCatch, iface) { for (size_t i = 0; i < iface.Iterations(); ++i) { try { ythrow yexception() << i; } catch (...) { Y_DO_NOT_OPTIMIZE_AWAY(CurrentExceptionMessage()); } } } Y_CPU_BENCHMARK(TestThrowCatchBT, iface) { for (size_t i = 0; i < iface.Iterations(); ++i) { try { ythrow TWithBackTrace() << i; } catch (...) { Y_DO_NOT_OPTIMIZE_AWAY(CurrentExceptionMessage()); } } } Y_CPU_BENCHMARK(TestRobust, iface) { if (iface.Iterations() % 100 == 0) { usleep(100000); } } Y_CPU_BENCHMARK(IterationSpeed, iface) { const auto n = iface.Iterations(); for (size_t i = 0; i < n; ++i) { Y_DO_NOT_OPTIMIZE_AWAY(i); } } Y_CPU_BENCHMARK(XRangeSpeed, iface) { for (auto i : xrange(0, iface.Iterations())) { Y_DO_NOT_OPTIMIZE_AWAY(i); } } Y_NO_INLINE int FFF() { return 0; } Y_NO_INLINE int FFF(int x) { return x; } Y_NO_INLINE int FFF(int x, int y) { return x + y; } Y_NO_INLINE size_t FS1(TStringBuf x) { return x.size(); } Y_NO_INLINE size_t FS1_2(TStringBuf x, TStringBuf y) { return x.size() + y.size(); } Y_NO_INLINE size_t FS2(const TStringBuf& x) { return x.size(); } Y_NO_INLINE size_t FS2_2(const TStringBuf& x, const TStringBuf& y) { return x.size() + y.size(); } Y_CPU_BENCHMARK(FunctionCallCost_StringBufVal1, iface) { TStringBuf x; for (auto i : xrange(0, iface.Iterations())) { (void)i; NBench::Escape(&x); Y_DO_NOT_OPTIMIZE_AWAY(FS1(x)); NBench::Clobber(); } } Y_CPU_BENCHMARK(FunctionCallCost_StringBufRef1, iface) { TStringBuf x; for (auto i : xrange(0, iface.Iterations())) { (void)i; NBench::Escape(&x); Y_DO_NOT_OPTIMIZE_AWAY(FS2(x)); NBench::Clobber(); } } Y_CPU_BENCHMARK(FunctionCallCost_StringBufVal2, iface) { TStringBuf x; TStringBuf y; for (auto i : xrange(0, iface.Iterations())) { (void)i; NBench::Escape(&x); NBench::Escape(&y); Y_DO_NOT_OPTIMIZE_AWAY(FS1_2(x, y)); NBench::Clobber(); } } Y_CPU_BENCHMARK(FunctionCallCost_StringBufRef2, iface) { TStringBuf x; TStringBuf y; for (auto i : xrange(0, iface.Iterations())) { (void)i; NBench::Escape(&x); NBench::Escape(&y); Y_DO_NOT_OPTIMIZE_AWAY(FS2_2(x, y)); NBench::Clobber(); } } Y_CPU_BENCHMARK(FunctionCallCost_NoArg, iface) { for (auto i : xrange(0, iface.Iterations())) { (void)i; Y_DO_NOT_OPTIMIZE_AWAY(FFF()); } } Y_CPU_BENCHMARK(FunctionCallCost_OneArg, iface) { for (auto i : xrange(0, iface.Iterations())) { Y_DO_NOT_OPTIMIZE_AWAY(FFF(i)); } } Y_CPU_BENCHMARK(FunctionCallCost_TwoArg, iface) { for (auto i : xrange(0, iface.Iterations())) { Y_DO_NOT_OPTIMIZE_AWAY(FFF(i, i)); } } /* An example of incorrect benchmark. As of r2581591 Clang 3.7 produced following assembly: * @code * │ push %rbp * │ mov %rsp,%rbp * │ push %rbx * │ push %rax * │ mov (%rdi),%rbx * │ test %rbx,%rbx * │ ↓ je 25 * │ xor %edi,%edi * │ xor %esi,%esi * │ → callq FS1(TBasicStringBuf(0, iface.Iterations())) { (void)i; Y_DO_NOT_OPTIMIZE_AWAY(FS1(x)); } }