Benchmark.tests.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. // Copyright Catch2 Authors
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // https://www.boost.org/LICENSE_1_0.txt)
  5. // SPDX-License-Identifier: BSL-1.0
  6. // Adapted from donated nonius code.
  7. #include <catch2/catch_test_macros.hpp>
  8. #include <catch2/benchmark/catch_benchmark.hpp>
  9. #include <catch2/benchmark/catch_constructor.hpp>
  10. #include <catch2/generators/catch_generators_range.hpp>
  11. #include <map>
  12. namespace {
  13. std::uint64_t Fibonacci(std::uint64_t number) {
  14. return number < 2 ? 1 : Fibonacci(number - 1) + Fibonacci(number - 2);
  15. }
  16. }
  17. TEST_CASE("Benchmark Fibonacci", "[!benchmark]") {
  18. CHECK(Fibonacci(0) == 1);
  19. // some more asserts..
  20. CHECK(Fibonacci(5) == 8);
  21. // some more asserts..
  22. BENCHMARK("Fibonacci 20") {
  23. return Fibonacci(20);
  24. };
  25. BENCHMARK("Fibonacci 25") {
  26. return Fibonacci(25);
  27. };
  28. BENCHMARK("Fibonacci 30") {
  29. return Fibonacci(30);
  30. };
  31. BENCHMARK("Fibonacci 35") {
  32. return Fibonacci(35);
  33. };
  34. }
  35. TEST_CASE("Benchmark containers", "[!benchmark]") {
  36. static const int size = 100;
  37. std::vector<int> v;
  38. std::map<int, int> m;
  39. SECTION("without generator") {
  40. BENCHMARK("Load up a vector") {
  41. v = std::vector<int>();
  42. for (int i = 0; i < size; ++i)
  43. v.push_back(i);
  44. };
  45. REQUIRE(v.size() == size);
  46. // test optimizer control
  47. BENCHMARK("Add up a vector's content") {
  48. uint64_t add = 0;
  49. for (int i = 0; i < size; ++i)
  50. add += v[i];
  51. return add;
  52. };
  53. BENCHMARK("Load up a map") {
  54. m = std::map<int, int>();
  55. for (int i = 0; i < size; ++i)
  56. m.insert({ i, i + 1 });
  57. };
  58. REQUIRE(m.size() == size);
  59. BENCHMARK("Reserved vector") {
  60. v = std::vector<int>();
  61. v.reserve(size);
  62. for (int i = 0; i < size; ++i)
  63. v.push_back(i);
  64. };
  65. REQUIRE(v.size() == size);
  66. BENCHMARK("Resized vector") {
  67. v = std::vector<int>();
  68. v.resize(size);
  69. for (int i = 0; i < size; ++i)
  70. v[i] = i;
  71. };
  72. REQUIRE(v.size() == size);
  73. int array[size];
  74. BENCHMARK("A fixed size array that should require no allocations") {
  75. for (int i = 0; i < size; ++i)
  76. array[i] = i;
  77. };
  78. int sum = 0;
  79. for (int i = 0; i < size; ++i)
  80. sum += array[i];
  81. REQUIRE(sum > size);
  82. SECTION("XYZ") {
  83. BENCHMARK_ADVANCED("Load up vector with chronometer")(Catch::Benchmark::Chronometer meter) {
  84. std::vector<int> k;
  85. meter.measure([&](int idx) {
  86. k = std::vector<int>();
  87. for (int i = 0; i < size; ++i)
  88. k.push_back(idx);
  89. });
  90. REQUIRE(k.size() == size);
  91. };
  92. int runs = 0;
  93. BENCHMARK("Fill vector indexed", benchmarkIndex) {
  94. v = std::vector<int>();
  95. v.resize(size);
  96. for (int i = 0; i < size; ++i)
  97. v[i] = benchmarkIndex;
  98. runs = benchmarkIndex;
  99. };
  100. for (size_t i = 0; i < v.size(); ++i) {
  101. REQUIRE(v[i] == runs);
  102. }
  103. }
  104. }
  105. SECTION("with generator") {
  106. auto generated = GENERATE(range(0, 10));
  107. BENCHMARK("Fill vector generated") {
  108. v = std::vector<int>();
  109. v.resize(size);
  110. for (int i = 0; i < size; ++i)
  111. v[i] = generated;
  112. };
  113. for (size_t i = 0; i < v.size(); ++i) {
  114. REQUIRE(v[i] == generated);
  115. }
  116. }
  117. SECTION("construct and destroy example") {
  118. BENCHMARK_ADVANCED("construct")(Catch::Benchmark::Chronometer meter) {
  119. std::vector<Catch::Benchmark::storage_for<std::string>> storage(meter.runs());
  120. meter.measure([&](int i) { storage[i].construct("thing"); });
  121. };
  122. BENCHMARK_ADVANCED("destroy")(Catch::Benchmark::Chronometer meter) {
  123. std::vector<Catch::Benchmark::destructable_object<std::string>> storage(meter.runs());
  124. for(auto&& o : storage)
  125. o.construct("thing");
  126. meter.measure([&](int i) { storage[i].destruct(); });
  127. };
  128. }
  129. }
  130. TEST_CASE("Skip benchmark macros", "[!benchmark]") {
  131. std::vector<int> v;
  132. BENCHMARK("fill vector") {
  133. v.emplace_back(1);
  134. v.emplace_back(2);
  135. v.emplace_back(3);
  136. };
  137. REQUIRE(v.size() == 0);
  138. std::size_t counter{0};
  139. BENCHMARK_ADVANCED("construct vector")(Catch::Benchmark::Chronometer meter) {
  140. std::vector<Catch::Benchmark::storage_for<std::string>> storage(meter.runs());
  141. meter.measure([&](int i) { storage[i].construct("thing"); counter++; });
  142. };
  143. REQUIRE(counter == 0);
  144. }