#include #include #include #include #include #include #include "benchmark/benchmark.h" #include "CartesianBenchmarks.h" #include "GenerateInput.h" namespace { template std::array every_10th_percentile_N(I first, N n) { N step = n / 10; std::array res; for (size_t i = 0; i < 10; ++i) { res[i] = first; std::advance(first, step); } return res; } template struct TestIntBase { static std::vector generateInput(size_t size) { std::vector Res(size); std::generate(Res.begin(), Res.end(), [] { return getRandomInteger(); }); return Res; } }; struct TestInt32 : TestIntBase { static constexpr const char* Name = "TestInt32"; }; struct TestInt64 : TestIntBase { static constexpr const char* Name = "TestInt64"; }; struct TestUint32 : TestIntBase { static constexpr const char* Name = "TestUint32"; }; struct TestMediumString { static constexpr const char* Name = "TestMediumString"; static constexpr size_t StringSize = 32; static std::vector generateInput(size_t size) { std::vector Res(size); std::generate(Res.begin(), Res.end(), [] { return getRandomString(StringSize); }); return Res; } }; using AllTestTypes = std::tuple; struct LowerBoundAlg { template I operator()(I first, I last, const V& value) const { return std::lower_bound(first, last, value); } static constexpr const char* Name = "LowerBoundAlg"; }; struct UpperBoundAlg { template I operator()(I first, I last, const V& value) const { return std::upper_bound(first, last, value); } static constexpr const char* Name = "UpperBoundAlg"; }; struct EqualRangeAlg { template std::pair operator()(I first, I last, const V& value) const { return std::equal_range(first, last, value); } static constexpr const char* Name = "EqualRangeAlg"; }; using AllAlgs = std::tuple; template struct PartitionPointBench { size_t Quantity; std::string name() const { return std::string("PartitionPointBench_") + Alg::Name + "_" + TestType::Name + '/' + std::to_string(Quantity); } void run(benchmark::State& state) const { auto Data = TestType::generateInput(Quantity); std::sort(Data.begin(), Data.end()); auto Every10Percentile = every_10th_percentile_N(Data.begin(), Data.size()); for (auto _ : state) { for (auto Test : Every10Percentile) benchmark::DoNotOptimize(Alg{}(Data.begin(), Data.end(), *Test)); } } }; } // namespace int main(int argc, char** argv) { benchmark::Initialize(&argc, argv); if (benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; const std::vector Quantities = {1 << 8, 1 << 10, 1 << 20}; makeCartesianProductBenchmark( Quantities); benchmark::RunSpecifiedBenchmarks(); }