1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03, c++11, c++14
18 #include "benchmark/benchmark.h"
20 #include "CartesianBenchmarks.h"
21 #include "GenerateInput.h"
25 template <typename I
, typename N
>
26 std::array
<I
, 10> every_10th_percentile_N(I first
, N n
) {
28 std::array
<I
, 10> res
;
30 for (size_t i
= 0; i
< 10; ++i
) {
32 std::advance(first
, step
);
40 static std::vector
<IntT
> generateInput(size_t size
) {
41 std::vector
<IntT
> Res(size
);
42 std::generate(Res
.begin(), Res
.end(), [] { return getRandomInteger
<IntT
>(0, std::numeric_limits
<IntT
>::max()); });
47 struct TestInt32
: TestIntBase
<std::int32_t> {
48 static constexpr const char* Name
= "TestInt32";
51 struct TestInt64
: TestIntBase
<std::int64_t> {
52 static constexpr const char* Name
= "TestInt64";
55 struct TestUint32
: TestIntBase
<std::uint32_t> {
56 static constexpr const char* Name
= "TestUint32";
59 struct TestMediumString
{
60 static constexpr const char* Name
= "TestMediumString";
61 static constexpr size_t StringSize
= 32;
63 static std::vector
<std::string
> generateInput(size_t size
) {
64 std::vector
<std::string
> Res(size
);
65 std::generate(Res
.begin(), Res
.end(), [] { return getRandomString(StringSize
); });
70 using AllTestTypes
= std::tuple
<TestInt32
, TestInt64
, TestUint32
, TestMediumString
>;
72 struct LowerBoundAlg
{
73 template <class I
, class V
>
74 I
operator()(I first
, I last
, const V
& value
) const {
75 return std::lower_bound(first
, last
, value
);
78 static constexpr const char* Name
= "LowerBoundAlg";
81 struct UpperBoundAlg
{
82 template <class I
, class V
>
83 I
operator()(I first
, I last
, const V
& value
) const {
84 return std::upper_bound(first
, last
, value
);
87 static constexpr const char* Name
= "UpperBoundAlg";
90 struct EqualRangeAlg
{
91 template <class I
, class V
>
92 std::pair
<I
, I
> operator()(I first
, I last
, const V
& value
) const {
93 return std::equal_range(first
, last
, value
);
96 static constexpr const char* Name
= "EqualRangeAlg";
99 using AllAlgs
= std::tuple
<LowerBoundAlg
, UpperBoundAlg
, EqualRangeAlg
>;
101 template <class Alg
, class TestType
>
102 struct PartitionPointBench
{
105 std::string
name() const {
106 return std::string("PartitionPointBench_") + Alg::Name
+ "_" + TestType::Name
+ '/' + std::to_string(Quantity
);
109 void run(benchmark::State
& state
) const {
110 auto Data
= TestType::generateInput(Quantity
);
111 std::sort(Data
.begin(), Data
.end());
112 auto Every10Percentile
= every_10th_percentile_N(Data
.begin(), Data
.size());
114 for (auto _
: state
) {
115 for (auto Test
: Every10Percentile
)
116 benchmark::DoNotOptimize(Alg
{}(Data
.begin(), Data
.end(), *Test
));
123 int main(int argc
, char** argv
) {
124 benchmark::Initialize(&argc
, argv
);
125 if (benchmark::ReportUnrecognizedArguments(argc
, argv
))
128 const std::vector
<size_t> Quantities
= {1 << 8, 1 << 10, 1 << 20};
129 makeCartesianProductBenchmark
<PartitionPointBench
, AllAlgs
, AllTestTypes
>(Quantities
);
130 benchmark::RunSpecifiedBenchmarks();