algorithms.bench.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #include <unordered_set>
  2. #include <vector>
  3. #include <cstdint>
  4. #include "benchmark/benchmark.h"
  5. #include "GenerateInput.hpp"
  6. constexpr std::size_t TestNumInputs = 1024;
  7. template <class GenInputs>
  8. void BM_Sort(benchmark::State& st, GenInputs gen) {
  9. using ValueType = typename decltype(gen(0))::value_type;
  10. const auto in = gen(st.range(0));
  11. std::vector<ValueType> inputs[5];
  12. auto reset_inputs = [&]() {
  13. for (auto& C : inputs) {
  14. C = in;
  15. benchmark::DoNotOptimize(C.data());
  16. }
  17. };
  18. reset_inputs();
  19. while (st.KeepRunning()) {
  20. for (auto& I : inputs) {
  21. std::sort(I.data(), I.data() + I.size());
  22. benchmark::DoNotOptimize(I.data());
  23. }
  24. st.PauseTiming();
  25. reset_inputs();
  26. benchmark::ClobberMemory();
  27. st.ResumeTiming();
  28. }
  29. }
  30. BENCHMARK_CAPTURE(BM_Sort, random_uint32,
  31. getRandomIntegerInputs<uint32_t>)->Arg(TestNumInputs);
  32. BENCHMARK_CAPTURE(BM_Sort, sorted_ascending_uint32,
  33. getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
  34. BENCHMARK_CAPTURE(BM_Sort, sorted_descending_uint32,
  35. getReverseSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
  36. BENCHMARK_CAPTURE(BM_Sort, single_element_uint32,
  37. getDuplicateIntegerInputs<uint32_t>)->Arg(TestNumInputs);
  38. BENCHMARK_CAPTURE(BM_Sort, pipe_organ_uint32,
  39. getPipeOrganIntegerInputs<uint32_t>)->Arg(TestNumInputs);
  40. BENCHMARK_CAPTURE(BM_Sort, random_strings,
  41. getRandomStringInputs)->Arg(TestNumInputs);
  42. BENCHMARK_CAPTURE(BM_Sort, sorted_ascending_strings,
  43. getSortedStringInputs)->Arg(TestNumInputs);
  44. BENCHMARK_CAPTURE(BM_Sort, sorted_descending_strings,
  45. getReverseSortedStringInputs)->Arg(TestNumInputs);
  46. BENCHMARK_CAPTURE(BM_Sort, single_element_strings,
  47. getDuplicateStringInputs)->Arg(TestNumInputs);
  48. template <typename GenInputs, typename Alg>
  49. void do_binary_search_benchmark(benchmark::State& st, GenInputs gen, Alg alg)
  50. {
  51. using ValueType = typename decltype(gen(0))::value_type;
  52. auto in = gen(st.range(0));
  53. std::sort(in.begin(), in.end());
  54. const auto every_10_percentile = [&]() -> std::vector<ValueType*> {
  55. size_t step = in.size() / 10;
  56. if (step == 0) {
  57. st.SkipWithError("Input doesn't contain enough elements");
  58. return {};
  59. }
  60. std::vector<ValueType*> res;
  61. for (size_t i = 0; i < in.size(); i += step)
  62. res.push_back(&in[i]);
  63. return res;
  64. }();
  65. for (auto _ : st)
  66. {
  67. for (auto* test : every_10_percentile)
  68. benchmark::DoNotOptimize(alg(in.begin(), in.end(), *test));
  69. }
  70. }
  71. template <typename GenInputs>
  72. void BM_LowerBound(benchmark::State& st, GenInputs gen)
  73. {
  74. do_binary_search_benchmark(st, gen, [](auto f, auto l, const auto& v) {
  75. return std::lower_bound(f, l, v);
  76. });
  77. }
  78. BENCHMARK_CAPTURE(BM_LowerBound, random_int32, getRandomIntegerInputs<int32_t>)
  79. ->Arg(TestNumInputs) // Small int32_t vector
  80. ->Arg(TestNumInputs * TestNumInputs); // Big int32_t vector
  81. BENCHMARK_CAPTURE(BM_LowerBound, random_int64, getRandomIntegerInputs<int64_t>)
  82. ->Arg(TestNumInputs); // Small int64_t vector. Should also represent pointers.
  83. BENCHMARK_CAPTURE(BM_LowerBound, random_strings, getRandomStringInputs)
  84. ->Arg(TestNumInputs); // Small string vector. What happens if the comparison is not very cheap.
  85. template <typename GenInputs>
  86. void BM_EqualRange(benchmark::State& st, GenInputs gen)
  87. {
  88. do_binary_search_benchmark(st, gen, [](auto f, auto l, const auto& v) {
  89. return std::equal_range(f, l, v);
  90. });
  91. }
  92. BENCHMARK_CAPTURE(BM_EqualRange, random_int32, getRandomIntegerInputs<int32_t>)
  93. ->Arg(TestNumInputs) // Small int32_t vector
  94. ->Arg(TestNumInputs * TestNumInputs); // Big int32_t vector
  95. BENCHMARK_CAPTURE(BM_EqualRange, random_int64, getRandomIntegerInputs<int64_t>)
  96. ->Arg(TestNumInputs); // Small int64_t vector. Should also represent pointers.
  97. BENCHMARK_CAPTURE(BM_EqualRange, random_strings, getRandomStringInputs)
  98. ->Arg(TestNumInputs); // Small string vector. What happens if the comparison is not very cheap.
  99. BENCHMARK_MAIN();