xref: /openbsd-src/gnu/llvm/libcxx/benchmarks/algorithms.partition_point.bench.cpp (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
146035553Spatrick #include <array>
246035553Spatrick #include <algorithm>
346035553Spatrick #include <cassert>
446035553Spatrick #include <cstdint>
546035553Spatrick #include <tuple>
646035553Spatrick #include <vector>
746035553Spatrick 
846035553Spatrick #include "benchmark/benchmark.h"
946035553Spatrick 
1046035553Spatrick #include "CartesianBenchmarks.h"
1146035553Spatrick #include "GenerateInput.h"
1246035553Spatrick 
1346035553Spatrick namespace {
1446035553Spatrick 
1546035553Spatrick template <typename I, typename N>
every_10th_percentile_N(I first,N n)1646035553Spatrick std::array<I, 10> every_10th_percentile_N(I first, N n) {
1746035553Spatrick   N step = n / 10;
1846035553Spatrick   std::array<I, 10> res;
1946035553Spatrick 
2046035553Spatrick   for (size_t i = 0; i < 10; ++i) {
2146035553Spatrick     res[i] = first;
2246035553Spatrick     std::advance(first, step);
2346035553Spatrick   }
2446035553Spatrick 
2546035553Spatrick   return res;
2646035553Spatrick }
2746035553Spatrick 
2846035553Spatrick template <class IntT>
2946035553Spatrick struct TestIntBase {
generateInput__anone332a8960111::TestIntBase3046035553Spatrick   static std::vector<IntT> generateInput(size_t size) {
3146035553Spatrick     std::vector<IntT> Res(size);
3246035553Spatrick     std::generate(Res.begin(), Res.end(),
33*4bdff4beSrobert                   [] { return getRandomInteger<IntT>(0, std::numeric_limits<IntT>::max()); });
3446035553Spatrick     return Res;
3546035553Spatrick   }
3646035553Spatrick };
3746035553Spatrick 
3846035553Spatrick struct TestInt32 : TestIntBase<std::int32_t> {
3946035553Spatrick   static constexpr const char* Name = "TestInt32";
4046035553Spatrick };
4146035553Spatrick 
4246035553Spatrick struct TestInt64 : TestIntBase<std::int64_t> {
4346035553Spatrick   static constexpr const char* Name = "TestInt64";
4446035553Spatrick };
4546035553Spatrick 
4646035553Spatrick struct TestUint32 : TestIntBase<std::uint32_t> {
4746035553Spatrick   static constexpr const char* Name = "TestUint32";
4846035553Spatrick };
4946035553Spatrick 
5046035553Spatrick struct TestMediumString {
5146035553Spatrick   static constexpr const char* Name = "TestMediumString";
5246035553Spatrick   static constexpr size_t StringSize = 32;
5346035553Spatrick 
generateInput__anone332a8960111::TestMediumString5446035553Spatrick   static std::vector<std::string> generateInput(size_t size) {
5546035553Spatrick     std::vector<std::string> Res(size);
5646035553Spatrick     std::generate(Res.begin(), Res.end(), [] { return getRandomString(StringSize); });
5746035553Spatrick     return Res;
5846035553Spatrick   }
5946035553Spatrick };
6046035553Spatrick 
6146035553Spatrick using AllTestTypes = std::tuple<TestInt32, TestInt64, TestUint32, TestMediumString>;
6246035553Spatrick 
6346035553Spatrick struct LowerBoundAlg {
6446035553Spatrick   template <class I, class V>
operator ()__anone332a8960111::LowerBoundAlg6546035553Spatrick   I operator()(I first, I last, const V& value) const {
6646035553Spatrick     return std::lower_bound(first, last, value);
6746035553Spatrick   }
6846035553Spatrick 
6946035553Spatrick   static constexpr const char* Name = "LowerBoundAlg";
7046035553Spatrick };
7146035553Spatrick 
7246035553Spatrick struct UpperBoundAlg {
7346035553Spatrick   template <class I, class V>
operator ()__anone332a8960111::UpperBoundAlg7446035553Spatrick   I operator()(I first, I last, const V& value) const {
7546035553Spatrick     return std::upper_bound(first, last, value);
7646035553Spatrick   }
7746035553Spatrick 
7846035553Spatrick   static constexpr const char* Name = "UpperBoundAlg";
7946035553Spatrick };
8046035553Spatrick 
8146035553Spatrick struct EqualRangeAlg {
8246035553Spatrick   template <class I, class V>
operator ()__anone332a8960111::EqualRangeAlg8346035553Spatrick   std::pair<I, I> operator()(I first, I last, const V& value) const {
8446035553Spatrick     return std::equal_range(first, last, value);
8546035553Spatrick   }
8646035553Spatrick 
8746035553Spatrick   static constexpr const char* Name = "EqualRangeAlg";
8846035553Spatrick };
8946035553Spatrick 
9046035553Spatrick using AllAlgs = std::tuple<LowerBoundAlg, UpperBoundAlg, EqualRangeAlg>;
9146035553Spatrick 
9246035553Spatrick template <class Alg, class TestType>
9346035553Spatrick struct PartitionPointBench {
9446035553Spatrick   size_t Quantity;
9546035553Spatrick 
name__anone332a8960111::PartitionPointBench9646035553Spatrick   std::string name() const {
9746035553Spatrick     return std::string("PartitionPointBench_") + Alg::Name + "_" +
9846035553Spatrick            TestType::Name + '/' + std::to_string(Quantity);
9946035553Spatrick   }
10046035553Spatrick 
run__anone332a8960111::PartitionPointBench10146035553Spatrick   void run(benchmark::State& state) const {
10246035553Spatrick     auto Data = TestType::generateInput(Quantity);
10346035553Spatrick     std::sort(Data.begin(), Data.end());
10446035553Spatrick     auto Every10Percentile = every_10th_percentile_N(Data.begin(), Data.size());
10546035553Spatrick 
10646035553Spatrick     for (auto _ : state) {
10746035553Spatrick       for (auto Test : Every10Percentile)
10846035553Spatrick         benchmark::DoNotOptimize(Alg{}(Data.begin(), Data.end(), *Test));
10946035553Spatrick     }
11046035553Spatrick   }
11146035553Spatrick };
11246035553Spatrick 
11346035553Spatrick } // namespace
11446035553Spatrick 
main(int argc,char ** argv)11546035553Spatrick int main(int argc, char** argv) {
11646035553Spatrick   benchmark::Initialize(&argc, argv);
11746035553Spatrick   if (benchmark::ReportUnrecognizedArguments(argc, argv))
11846035553Spatrick     return 1;
11946035553Spatrick 
12046035553Spatrick   const std::vector<size_t> Quantities = {1 << 8, 1 << 10, 1 << 20};
12146035553Spatrick   makeCartesianProductBenchmark<PartitionPointBench, AllAlgs, AllTestTypes>(
12246035553Spatrick       Quantities);
12346035553Spatrick   benchmark::RunSpecifiedBenchmarks();
12446035553Spatrick }
125