diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /util/generic/benchmark | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'util/generic/benchmark')
32 files changed, 1037 insertions, 0 deletions
diff --git a/util/generic/benchmark/cont_speed/main.cpp b/util/generic/benchmark/cont_speed/main.cpp new file mode 100644 index 00000000000..01428c99747 --- /dev/null +++ b/util/generic/benchmark/cont_speed/main.cpp @@ -0,0 +1,117 @@ +#include <library/cpp/testing/benchmark/bench.h> + +#include <util/generic/xrange.h> +#include <util/generic/string.h> +#include <util/generic/vector.h> +#include <util/generic/buffer.h> + +template <class C> +Y_NO_INLINE void Run(const C& c) { + for (size_t i = 0; i < c.size(); ++i) { + Y_DO_NOT_OPTIMIZE_AWAY(c[i]); + } +} + +template <class C> +void Do(size_t len, auto& iface) { + C c(len, 0); + + for (auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + Run(c); + } +} + +Y_CPU_BENCHMARK(TVector10, iface) { + Do<TVector<char>>(10, iface); +} + +Y_CPU_BENCHMARK(TVector100, iface) { + Do<TVector<char>>(100, iface); +} + +Y_CPU_BENCHMARK(TVector1000, iface) { + Do<TVector<char>>(1000, iface); +} + +Y_CPU_BENCHMARK(TString10, iface) { + Do<TString>(10, iface); +} + +Y_CPU_BENCHMARK(TString100, iface) { + Do<TString>(100, iface); +} + +Y_CPU_BENCHMARK(TString1000, iface) { + Do<TString>(1000, iface); +} + +Y_CPU_BENCHMARK(StdString10, iface) { + Do<std::string>(10, iface); +} + +Y_CPU_BENCHMARK(StdString100, iface) { + Do<std::string>(100, iface); +} + +Y_CPU_BENCHMARK(StdString1000, iface) { + Do<std::string>(1000, iface); +} + +struct TBuf: public TBuffer { + TBuf(size_t len, char v) { + for (size_t i = 0; i < len; ++i) { + Append(v); + } + } + + inline const auto& operator[](size_t i) const noexcept { + return *(data() + i); + } +}; + +Y_CPU_BENCHMARK(TBuffer10, iface) { + Do<TBuf>(10, iface); +} + +Y_CPU_BENCHMARK(TBuffer100, iface) { + Do<TBuf>(100, iface); +} + +Y_CPU_BENCHMARK(TBuffer1000, iface) { + Do<TBuf>(1000, iface); +} + +struct TArr { + inline TArr(size_t len, char ch) + : A(new char[len]) + , L(len) + { + for (size_t i = 0; i < L; ++i) { + A[i] = ch; + } + } + + inline const auto& operator[](size_t i) const noexcept { + return A[i]; + } + + inline size_t size() const noexcept { + return L; + } + + char* A; + size_t L; +}; + +Y_CPU_BENCHMARK(Pointer10, iface) { + Do<TArr>(10, iface); +} + +Y_CPU_BENCHMARK(Pointer100, iface) { + Do<TArr>(100, iface); +} + +Y_CPU_BENCHMARK(Pointer1000, iface) { + Do<TArr>(1000, iface); +} diff --git a/util/generic/benchmark/cont_speed/ya.make b/util/generic/benchmark/cont_speed/ya.make new file mode 100644 index 00000000000..6ff3fe767c0 --- /dev/null +++ b/util/generic/benchmark/cont_speed/ya.make @@ -0,0 +1,9 @@ +Y_BENCHMARK() + +OWNER(g:util) + +SRCS( + main.cpp +) + +END() diff --git a/util/generic/benchmark/fastclp2/main.cpp b/util/generic/benchmark/fastclp2/main.cpp new file mode 100644 index 00000000000..49277db077c --- /dev/null +++ b/util/generic/benchmark/fastclp2/main.cpp @@ -0,0 +1,50 @@ +#include <library/cpp/testing/benchmark/bench.h> + +#include <util/generic/bitops.h> +#include <util/generic/vector.h> +#include <util/generic/xrange.h> +#include <util/generic/singleton.h> + +#include <util/random/fast.h> + +namespace { + template <typename T, size_t N> + struct TExamplesHolder { + TExamplesHolder() + : Examples(N) + { + TFastRng<ui64> prng{42u * sizeof(T) * N}; + for (auto& x : Examples) { + x = prng(); + } + } + + TVector<T> Examples; + }; +} + +#define DEFINE_BENCHMARK(type, count) \ + Y_CPU_BENCHMARK(FastClp2_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(FastClp2(e)); \ + } \ + } \ + } + +DEFINE_BENCHMARK(ui8, 1) +DEFINE_BENCHMARK(ui8, 10) +DEFINE_BENCHMARK(ui8, 100) +DEFINE_BENCHMARK(ui16, 1) +DEFINE_BENCHMARK(ui16, 10) +DEFINE_BENCHMARK(ui16, 100) +DEFINE_BENCHMARK(ui32, 1) +DEFINE_BENCHMARK(ui32, 10) +DEFINE_BENCHMARK(ui32, 100) +DEFINE_BENCHMARK(ui64, 1) +DEFINE_BENCHMARK(ui64, 10) +DEFINE_BENCHMARK(ui64, 100) + +#undef DEFINE_BENCHMARKS diff --git a/util/generic/benchmark/fastclp2/metrics/main.py b/util/generic/benchmark/fastclp2/metrics/main.py new file mode 100644 index 00000000000..5573c6a5d7f --- /dev/null +++ b/util/generic/benchmark/fastclp2/metrics/main.py @@ -0,0 +1,5 @@ +import yatest.common as yc + + +def test_export_metrics(metrics): + metrics.set_benchmark(yc.execute_benchmark('util/generic/benchmark/fastclp2/fastclp2', threads=8)) diff --git a/util/generic/benchmark/fastclp2/metrics/ya.make b/util/generic/benchmark/fastclp2/metrics/ya.make new file mode 100644 index 00000000000..b2d17ebad34 --- /dev/null +++ b/util/generic/benchmark/fastclp2/metrics/ya.make @@ -0,0 +1,21 @@ +OWNER( + yazevnul + g:util +) +SUBSCRIBER(g:util-subscribers) + +PY2TEST() + +SIZE(LARGE) + +TAG( + ya:force_sandbox + sb:intel_e5_2660v1 + ya:fat +) + +TEST_SRCS(main.py) + +DEPENDS(util/generic/benchmark/fastclp2) + +END() diff --git a/util/generic/benchmark/fastclp2/ya.make b/util/generic/benchmark/fastclp2/ya.make new file mode 100644 index 00000000000..976977014f6 --- /dev/null +++ b/util/generic/benchmark/fastclp2/ya.make @@ -0,0 +1,13 @@ +OWNER( + yazevnul + g:util +) +SUBSCRIBER(g:util-subscribers) + +Y_BENCHMARK() + +SRCS( + main.cpp +) + +END() diff --git a/util/generic/benchmark/log2/main.cpp b/util/generic/benchmark/log2/main.cpp new file mode 100644 index 00000000000..969f09a3090 --- /dev/null +++ b/util/generic/benchmark/log2/main.cpp @@ -0,0 +1,140 @@ +#include <library/cpp/testing/benchmark/bench.h> + +#include <library/cpp/fast_log/fast_log.h> + +#include <util/generic/singleton.h> +#include <util/generic/vector.h> +#include <util/random/fast.h> +#include <util/generic/xrange.h> + +#include <cmath> +namespace { + template <typename T, size_t N> + struct TExamplesHolder { + TVector<T> Examples; + + TExamplesHolder() + : Examples(N) + { + TFastRng<ui64> prng{N * 42}; + for (auto& x : Examples) { + x = prng.GenRandReal4() + prng.Uniform(1932); // 1934 is just a random number + } + } + }; +} + +#define DEFINE_BENCHMARK(type, count) \ + Y_CPU_BENCHMARK(libm_log2f_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(log2f(e)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(libm_logf_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(logf(e)); \ + } \ + } \ + } \ + Y_CPU_BENCHMARK(STL_Log2_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(std::log2(e)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(STL_Log_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(std::log(e)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(Fast_Log2_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(FastLog2f(e)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(FastLogf##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(FastLogf(e)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(Faster_Log2_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(FasterLog2f(e)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(Faster_Log_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(FasterLogf(e)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(Fastest_Log2f_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(FastestLog2f(e)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(Fastest_Log_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(FastestLogf(e)); \ + } \ + } \ + } + +DEFINE_BENCHMARK(float, 1) +DEFINE_BENCHMARK(float, 2) +DEFINE_BENCHMARK(float, 4) +DEFINE_BENCHMARK(float, 8) +DEFINE_BENCHMARK(float, 16) +DEFINE_BENCHMARK(float, 32) +DEFINE_BENCHMARK(float, 64) +DEFINE_BENCHMARK(float, 128) +DEFINE_BENCHMARK(float, 256) +DEFINE_BENCHMARK(float, 1024) +DEFINE_BENCHMARK(float, 2048) +DEFINE_BENCHMARK(float, 4096) + +#undef DEFINE_BENCHMARK diff --git a/util/generic/benchmark/log2/metrics/main.py b/util/generic/benchmark/log2/metrics/main.py new file mode 100644 index 00000000000..26f6b57812b --- /dev/null +++ b/util/generic/benchmark/log2/metrics/main.py @@ -0,0 +1,5 @@ +import yatest.common as yc + + +def test_export_metrics(metrics): + metrics.set_benchmark(yc.execute_benchmark('util/generic/benchmark/log2/log2', threads=8)) diff --git a/util/generic/benchmark/log2/metrics/ya.make b/util/generic/benchmark/log2/metrics/ya.make new file mode 100644 index 00000000000..eb987e38d25 --- /dev/null +++ b/util/generic/benchmark/log2/metrics/ya.make @@ -0,0 +1,21 @@ +OWNER( + yazevnul + g:util +) +SUBSCRIBER(g:util-subscribers) + +PY2TEST() + +SIZE(LARGE) + +TAG( + ya:force_sandbox + sb:intel_e5_2660v1 + ya:fat +) + +TEST_SRCS(main.py) + +DEPENDS(util/generic/benchmark/log2) + +END() diff --git a/util/generic/benchmark/log2/ya.make b/util/generic/benchmark/log2/ya.make new file mode 100644 index 00000000000..45d751909ea --- /dev/null +++ b/util/generic/benchmark/log2/ya.make @@ -0,0 +1,17 @@ +OWNER( + yazevnul + g:util +) +SUBSCRIBER(g:util-subscribers) + +Y_BENCHMARK() + +SRCS( + main.cpp +) + +PEERDIR( + library/cpp/fast_log +) + +END() diff --git a/util/generic/benchmark/rotate_bits/main.cpp b/util/generic/benchmark/rotate_bits/main.cpp new file mode 100644 index 00000000000..057edbe864f --- /dev/null +++ b/util/generic/benchmark/rotate_bits/main.cpp @@ -0,0 +1,66 @@ +#include <library/cpp/testing/benchmark/bench.h> + +#include <util/generic/vector.h> +#include <util/generic/xrange.h> +#include <util/generic/singleton.h> + +#include <util/random/fast.h> + +namespace { + template <typename T> + struct TExample { + T Value; + ui8 Shift; + }; + + template <typename T, size_t N> + struct TExamplesHolder { + TExamplesHolder() + : Examples(N) + { + TFastRng<ui64> prng{42u * sizeof(T) * N}; + for (auto& e : Examples) { + e.Value = prng(); + e.Shift = prng() % (8 * sizeof(T)); + } + } + + TVector<TExample<T>> Examples; + }; +} + +#define DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES(type, count) \ + Y_CPU_BENCHMARK(LeftRotate_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(RotateBitsLeft(e.Value, e.Shift)); \ + } \ + } \ + } \ + \ + Y_CPU_BENCHMARK(RightRotate_##type##_##count, iface) { \ + const auto& examples = Default<TExamplesHolder<type, count>>().Examples; \ + for (const auto i : xrange(iface.Iterations())) { \ + Y_UNUSED(i); \ + for (const auto e : examples) { \ + Y_DO_NOT_OPTIMIZE_AWAY(RotateBitsRight(e.Value, e.Shift)); \ + } \ + } \ + } + +DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES(ui8, 1) +DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES(ui8, 10) +DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES(ui8, 100) +DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES(ui16, 1) +DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES(ui16, 10) +DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES(ui16, 100) +DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES(ui32, 1) +DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES(ui32, 10) +DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES(ui32, 100) +DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES(ui64, 1) +DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES(ui64, 10) +DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES(ui64, 100) + +#undef DEFINE_BENCHMARKS_FOR_UNSIGNED_TYPES diff --git a/util/generic/benchmark/rotate_bits/metrics/main.py b/util/generic/benchmark/rotate_bits/metrics/main.py new file mode 100644 index 00000000000..b30555775f9 --- /dev/null +++ b/util/generic/benchmark/rotate_bits/metrics/main.py @@ -0,0 +1,5 @@ +import yatest.common as yc + + +def test_export_metrics(metrics): + metrics.set_benchmark(yc.execute_benchmark('util/generic/benchmark/rotate_bits/rotate_bits', threads=8)) diff --git a/util/generic/benchmark/rotate_bits/metrics/ya.make b/util/generic/benchmark/rotate_bits/metrics/ya.make new file mode 100644 index 00000000000..ac27d2f845f --- /dev/null +++ b/util/generic/benchmark/rotate_bits/metrics/ya.make @@ -0,0 +1,21 @@ +OWNER( + yazevnul + g:util +) +SUBSCRIBER(g:util-subscribers) + +PY2TEST() + +SIZE(LARGE) + +TAG( + ya:force_sandbox + sb:intel_e5_2660v1 + ya:fat +) + +TEST_SRCS(main.py) + +DEPENDS(util/generic/benchmark/rotate_bits) + +END() diff --git a/util/generic/benchmark/rotate_bits/ya.make b/util/generic/benchmark/rotate_bits/ya.make new file mode 100644 index 00000000000..976977014f6 --- /dev/null +++ b/util/generic/benchmark/rotate_bits/ya.make @@ -0,0 +1,13 @@ +OWNER( + yazevnul + g:util +) +SUBSCRIBER(g:util-subscribers) + +Y_BENCHMARK() + +SRCS( + main.cpp +) + +END() diff --git a/util/generic/benchmark/singleton/f.cpp b/util/generic/benchmark/singleton/f.cpp new file mode 100644 index 00000000000..bf6da53d9c0 --- /dev/null +++ b/util/generic/benchmark/singleton/f.cpp @@ -0,0 +1,18 @@ +#include <util/generic/singleton.h> + +struct X { + inline X() { + } + + char Buf[100]; +}; + +char& FF1() noexcept { + static X x; + + return x.Buf[0]; +} + +char& FF2() noexcept { + return Singleton<X>()->Buf[0]; +} diff --git a/util/generic/benchmark/singleton/main.cpp b/util/generic/benchmark/singleton/main.cpp new file mode 100644 index 00000000000..2b06bd371d7 --- /dev/null +++ b/util/generic/benchmark/singleton/main.cpp @@ -0,0 +1,54 @@ +#include <library/cpp/testing/benchmark/bench.h> + +#include <util/generic/singleton.h> +#include <util/generic/xrange.h> + +char& FF1() noexcept; +char& FF2() noexcept; + +namespace { + struct X { + inline X() { + } + + char Buf[100]; + }; + + inline X& F1() noexcept { + static X x; + + return x; + } + + inline X& F2() noexcept { + return *Singleton<X>(); + } +} + +Y_CPU_BENCHMARK(MagicStatic, iface) { + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + Y_DO_NOT_OPTIMIZE_AWAY(F1().Buf); + } +} + +Y_CPU_BENCHMARK(Singleton, iface) { + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + Y_DO_NOT_OPTIMIZE_AWAY(F2().Buf); + } +} + +Y_CPU_BENCHMARK(MagicStaticNI, iface) { + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + Y_DO_NOT_OPTIMIZE_AWAY(FF1()); + } +} + +Y_CPU_BENCHMARK(SingletonNI, iface) { + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + Y_DO_NOT_OPTIMIZE_AWAY(FF2()); + } +} diff --git a/util/generic/benchmark/singleton/ya.make b/util/generic/benchmark/singleton/ya.make new file mode 100644 index 00000000000..12d3d316c86 --- /dev/null +++ b/util/generic/benchmark/singleton/ya.make @@ -0,0 +1,11 @@ +Y_BENCHMARK() + +OWNER(g:util) +SUBSCRIBER(g:util-subscribers) + +SRCS( + f.cpp + main.cpp +) + +END() diff --git a/util/generic/benchmark/smart_pointers/main.cpp b/util/generic/benchmark/smart_pointers/main.cpp new file mode 100644 index 00000000000..92c2f923bb7 --- /dev/null +++ b/util/generic/benchmark/smart_pointers/main.cpp @@ -0,0 +1,14 @@ +#include <library/cpp/testing/benchmark/bench.h> + +#include <util/generic/ptr.h> +#include <util/generic/xrange.h> + +struct X: public TAtomicRefCount<X> { +}; + +Y_CPU_BENCHMARK(SimplePtrConstruct, iface) { + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + Y_DO_NOT_OPTIMIZE_AWAY(TSimpleIntrusivePtr<X>()); + } +} diff --git a/util/generic/benchmark/smart_pointers/ya.make b/util/generic/benchmark/smart_pointers/ya.make new file mode 100644 index 00000000000..7059abc3a4c --- /dev/null +++ b/util/generic/benchmark/smart_pointers/ya.make @@ -0,0 +1,10 @@ +Y_BENCHMARK() + +OWNER(g:util) +SUBSCRIBER(g:util-subscribers) + +SRCS( + main.cpp +) + +END() diff --git a/util/generic/benchmark/sort/main.cpp b/util/generic/benchmark/sort/main.cpp new file mode 100644 index 00000000000..d58f491f4d5 --- /dev/null +++ b/util/generic/benchmark/sort/main.cpp @@ -0,0 +1,77 @@ +#include <library/cpp/testing/benchmark/bench.h> + +#include <util/generic/algorithm.h> +#include <util/generic/vector.h> +#include <util/generic/xrange.h> + +Y_CPU_BENCHMARK(Sort1, iface) { + TVector<int> x = {1}; + + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + Sort(x); + } +} + +Y_CPU_BENCHMARK(Sort2, iface) { + TVector<int> x = {2, 1}; + + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + Sort(x); + } +} + +Y_CPU_BENCHMARK(Sort4, iface) { + TVector<int> x = {4, 3, 2, 1}; + + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + Sort(x); + } +} + +Y_CPU_BENCHMARK(Sort16, iface) { + TVector<int> x = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; + + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + Sort(x); + } +} + +Y_CPU_BENCHMARK(StableSort1, iface) { + TVector<int> x = {1}; + + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + StableSort(x); + } +} + +Y_CPU_BENCHMARK(StableSort2, iface) { + TVector<int> x = {2, 1}; + + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + StableSort(x); + } +} + +Y_CPU_BENCHMARK(StableSort4, iface) { + TVector<int> x = {4, 3, 2, 1}; + + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + StableSort(x); + } +} + +Y_CPU_BENCHMARK(StableSort16, iface) { + TVector<int> x = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; + + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + StableSort(x); + } +} diff --git a/util/generic/benchmark/sort/ya.make b/util/generic/benchmark/sort/ya.make new file mode 100644 index 00000000000..7059abc3a4c --- /dev/null +++ b/util/generic/benchmark/sort/ya.make @@ -0,0 +1,10 @@ +Y_BENCHMARK() + +OWNER(g:util) +SUBSCRIBER(g:util-subscribers) + +SRCS( + main.cpp +) + +END() diff --git a/util/generic/benchmark/string/benchmarks.h b/util/generic/benchmark/string/benchmarks.h new file mode 100644 index 00000000000..e347d7ff474 --- /dev/null +++ b/util/generic/benchmark/string/benchmarks.h @@ -0,0 +1,188 @@ +#pragma once + +// Define BENCHMARK_PREFIX and BENCHMARKED_CLASS before including this file. + +#include <util/generic/xrange.h> + +#define Y_CPU_PREFIXED_BENCHMARK_HELPER(prefix, name, iface) Y_CPU_BENCHMARK(prefix##name, iface) +#define Y_CPU_PREFIXED_BENCHMARK(prefix, name, iface) Y_CPU_PREFIXED_BENCHMARK_HELPER(prefix, name, iface) +#define CONCATENATE3_HELPER(a, b, c) a##b##c +#define CONCATENATE3(a, b, c) CONCATENATE3_HELPER(a, b, c) + +namespace { + namespace CONCATENATE3(N, BENCHMARK_PREFIX, Benchmark) { + using TBenchmarkedClass = BENCHMARKED_CLASS; + + const auto defaultString = TBenchmarkedClass(); + const auto emptyString = TBenchmarkedClass(""); + const auto lengthOneString = TBenchmarkedClass("1"); + const auto length1KString = TBenchmarkedClass(1000, '1'); + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CreateDefault, iface) { + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto result = TBenchmarkedClass(); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CreateFromEmptyLiteral, iface) { + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto result = TBenchmarkedClass(""); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CreateFromLengthOneLiteral, iface) { + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto result = TBenchmarkedClass("1"); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CreateLength1K, iface) { + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto result = TBenchmarkedClass(1000, '1'); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyDefaultString, iface) { + const auto& sourceString = defaultString; + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto result = TBenchmarkedClass(sourceString); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyEmptyString, iface) { + const auto& sourceString = emptyString; + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto result = TBenchmarkedClass(sourceString); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyLengthOneString, iface) { + const auto& sourceString = lengthOneString; + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto result = TBenchmarkedClass(sourceString); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyLength1KString, iface) { + const auto& sourceString = length1KString; + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto result = TBenchmarkedClass(sourceString); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndUpdateLengthOneString, iface) { + const auto& sourceString = lengthOneString; + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto targetString = TBenchmarkedClass(sourceString); + auto result = targetString[0] = '0'; + Y_DO_NOT_OPTIMIZE_AWAY(targetString); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndAppendDefaultString, iface) { + const auto& sourceString = defaultString; + const TBenchmarkedClass::size_type insertPosition = sourceString.size(); + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto targetString = TBenchmarkedClass(sourceString); + auto result = targetString.insert(insertPosition, 1, '0'); + Y_DO_NOT_OPTIMIZE_AWAY(targetString); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndAppendEmptyString, iface) { + const auto& sourceString = emptyString; + const TBenchmarkedClass::size_type insertPosition = sourceString.size(); + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto targetString = TBenchmarkedClass(sourceString); + auto result = targetString.insert(insertPosition, 1, '0'); + Y_DO_NOT_OPTIMIZE_AWAY(targetString); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndAppendLengthOneString, iface) { + const auto& sourceString = lengthOneString; + const TBenchmarkedClass::size_type insertPosition = sourceString.size(); + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto targetString = TBenchmarkedClass(sourceString); + auto result = targetString.insert(insertPosition, 1, '0'); + Y_DO_NOT_OPTIMIZE_AWAY(targetString); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndPrependLengthOneString, iface) { + const auto& sourceString = lengthOneString; + const TBenchmarkedClass::size_type insertPosition = 0; + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto targetString = TBenchmarkedClass(sourceString); + auto result = targetString.insert(insertPosition, 1, '0'); + Y_DO_NOT_OPTIMIZE_AWAY(targetString); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndUpdateLength1KString, iface) { + const auto& sourceString = length1KString; + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto targetString = TBenchmarkedClass(sourceString); + auto result = targetString[0] = '0'; + Y_DO_NOT_OPTIMIZE_AWAY(targetString); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndAppendLength1KString, iface) { + const auto& sourceString = length1KString; + const TBenchmarkedClass::size_type insertPosition = sourceString.size(); + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto targetString = TBenchmarkedClass(sourceString); + auto result = targetString.insert(insertPosition, 1, '0'); + Y_DO_NOT_OPTIMIZE_AWAY(targetString); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + + Y_CPU_PREFIXED_BENCHMARK(BENCHMARK_PREFIX, CopyAndPrependLength1KString, iface) { + const auto& sourceString = length1KString; + const TBenchmarkedClass::size_type insertPosition = 0; + for (const auto i : xrange(iface.Iterations())) { + Y_UNUSED(i); + auto targetString = TBenchmarkedClass(sourceString); + auto result = targetString.insert(insertPosition, 1, '0'); + Y_DO_NOT_OPTIMIZE_AWAY(targetString); + Y_DO_NOT_OPTIMIZE_AWAY(result); + } + } + } +} + +#undef CONCATENATE3 +#undef CONCATENATE3_HELPER +#undef Y_CPU_PREFIXED_BENCHMARK +#undef Y_CPU_PREFIXED_BENCHMARK_HELPER diff --git a/util/generic/benchmark/string/std_string.cpp b/util/generic/benchmark/string/std_string.cpp new file mode 100644 index 00000000000..cb10b4dc0c6 --- /dev/null +++ b/util/generic/benchmark/string/std_string.cpp @@ -0,0 +1,8 @@ +#include <library/cpp/testing/benchmark/bench.h> + +#include <string> + +#define BENCHMARK_PREFIX StdString +#define BENCHMARKED_CLASS std::string + +#include "benchmarks.h" diff --git a/util/generic/benchmark/string/string.cpp b/util/generic/benchmark/string/string.cpp new file mode 100644 index 00000000000..c634c204d84 --- /dev/null +++ b/util/generic/benchmark/string/string.cpp @@ -0,0 +1,8 @@ +#include <library/cpp/testing/benchmark/bench.h> + +#include <util/generic/string.h> + +#define BENCHMARK_PREFIX TString +#define BENCHMARKED_CLASS ::TString + +#include "benchmarks.h" diff --git a/util/generic/benchmark/string/ya.make b/util/generic/benchmark/string/ya.make new file mode 100644 index 00000000000..c2956de6a18 --- /dev/null +++ b/util/generic/benchmark/string/ya.make @@ -0,0 +1,11 @@ +Y_BENCHMARK() + +OWNER(g:util) +SUBSCRIBER(g:util-subscribers) + +SRCS( + string.cpp + std_string.cpp +) + +END() diff --git a/util/generic/benchmark/vector_count_ctor/f.cpp b/util/generic/benchmark/vector_count_ctor/f.cpp new file mode 100644 index 00000000000..b89e351ba72 --- /dev/null +++ b/util/generic/benchmark/vector_count_ctor/f.cpp @@ -0,0 +1,25 @@ +#include "f.h" + +#include <library/cpp/testing/benchmark/bench.h> + +#include <util/generic/vector.h> +#include <util/generic/ptr.h> + +void CreateYvector(const size_t size, const size_t count) { + for (size_t i = 0; i < count; ++i) { + NBench::Clobber(); + TVector<ui8> v(size); + NBench::Escape(v.data()); + NBench::Clobber(); + } +} + +void CreateCarray(const size_t size, const size_t count) { + for (size_t i = 0; i < count; ++i) { + NBench::Clobber(); + TArrayHolder<ui8> v(new ui8[size]); + memset(v.Get(), 0, size * sizeof(ui8)); + NBench::Escape(v.Get()); + NBench::Clobber(); + } +} diff --git a/util/generic/benchmark/vector_count_ctor/f.h b/util/generic/benchmark/vector_count_ctor/f.h new file mode 100644 index 00000000000..a568341a456 --- /dev/null +++ b/util/generic/benchmark/vector_count_ctor/f.h @@ -0,0 +1,9 @@ +#pragma once + +#include <cstddef> + +// functions are declared in a separate translation unit so that compiler won't be able to see the +// value of `size` during compilation. + +void CreateYvector(const size_t size, const size_t count); +void CreateCarray(const size_t size, const size_t count); diff --git a/util/generic/benchmark/vector_count_ctor/main.cpp b/util/generic/benchmark/vector_count_ctor/main.cpp new file mode 100644 index 00000000000..6fb1fda9c94 --- /dev/null +++ b/util/generic/benchmark/vector_count_ctor/main.cpp @@ -0,0 +1,30 @@ +#include "f.h" + +#include <library/cpp/testing/benchmark/bench.h> + +#define DEFINE_BENCHMARK(N) \ + Y_CPU_BENCHMARK(Yvector_##N, iface) { \ + CreateYvector(N, iface.Iterations()); \ + } \ + Y_CPU_BENCHMARK(Carray_##N, iface) { \ + CreateCarray(N, iface.Iterations()); \ + } + +DEFINE_BENCHMARK(1) +DEFINE_BENCHMARK(2) +DEFINE_BENCHMARK(8) +DEFINE_BENCHMARK(10) +DEFINE_BENCHMARK(16) +DEFINE_BENCHMARK(20) +DEFINE_BENCHMARK(1000) +DEFINE_BENCHMARK(1024) +DEFINE_BENCHMARK(8192) +DEFINE_BENCHMARK(10000) +DEFINE_BENCHMARK(65536) +DEFINE_BENCHMARK(100000) +DEFINE_BENCHMARK(4194304) +DEFINE_BENCHMARK(1000000) +DEFINE_BENCHMARK(33554432) +DEFINE_BENCHMARK(10000000) +DEFINE_BENCHMARK(268435456) +DEFINE_BENCHMARK(100000000) diff --git a/util/generic/benchmark/vector_count_ctor/metrics/main.py b/util/generic/benchmark/vector_count_ctor/metrics/main.py new file mode 100644 index 00000000000..835b44fe5f7 --- /dev/null +++ b/util/generic/benchmark/vector_count_ctor/metrics/main.py @@ -0,0 +1,5 @@ +import yatest.common as yc + + +def test_export_metrics(metrics): + metrics.set_benchmark(yc.execute_benchmark('util/generic/benchmark/vector_count_ctor/vector_count_ctor', threads=8)) diff --git a/util/generic/benchmark/vector_count_ctor/metrics/ya.make b/util/generic/benchmark/vector_count_ctor/metrics/ya.make new file mode 100644 index 00000000000..c48f89b564a --- /dev/null +++ b/util/generic/benchmark/vector_count_ctor/metrics/ya.make @@ -0,0 +1,21 @@ +OWNER( + yazevnul + g:util +) +SUBSCRIBER(g:util-subscribers) + +PY2TEST() + +SIZE(LARGE) + +TAG( + ya:force_sandbox + sb:intel_e5_2660v1 + ya:fat +) + +TEST_SRCS(main.py) + +DEPENDS(util/generic/benchmark/vector_count_ctor) + +END() diff --git a/util/generic/benchmark/vector_count_ctor/ya.make b/util/generic/benchmark/vector_count_ctor/ya.make new file mode 100644 index 00000000000..42ce4428194 --- /dev/null +++ b/util/generic/benchmark/vector_count_ctor/ya.make @@ -0,0 +1,16 @@ +OWNER( + yazevnul + g:util +) +SUBSCRIBER(g:util-subscribers) + +Y_BENCHMARK() + +ALLOCATOR(B) + +SRCS( + main.cpp + f.cpp +) + +END() diff --git a/util/generic/benchmark/ya.make b/util/generic/benchmark/ya.make new file mode 100644 index 00000000000..635860a646c --- /dev/null +++ b/util/generic/benchmark/ya.make @@ -0,0 +1,19 @@ +OWNER(yazevnul g:util) + +SUBSCRIBER(g:util-subscribers) + +RECURSE( + fastclp2 + fastclp2/metrics + log2 + log2/metrics + rotate_bits + rotate_bits/metrics + singleton + smart_pointers + sort + string + vector_count_ctor + vector_count_ctor/metrics + cont_speed +) |