@@ -38,9 +38,8 @@ int main(int argc, char** argv) {
38
38
});
39
39
};
40
40
41
- // Benchmark {std,ranges}::find_first_of where we have a hit at 10% of the haystack
42
- // and at the end of the needle. This measures how quickly we're able to search inside
43
- // the needle.
41
+ // Benchmark {std,ranges}::find_first_of where we never find a match in the needle, and the needle is small.
42
+ // This is the worst case of the most common case (a small needle).
44
43
{
45
44
auto bm = []<class Container >(std::string name, auto find_first_of) {
46
45
benchmark::RegisterBenchmark (
@@ -50,13 +49,8 @@ int main(int argc, char** argv) {
50
49
using ValueType = typename Container::value_type;
51
50
ValueType x = Generate<ValueType>::random ();
52
51
ValueType y = random_different_from ({x});
53
- ValueType z = random_different_from ({x, y});
54
52
Container haystack (size, x);
55
- Container needle (size, y);
56
- needle.back () = z; // hit at the very end of the needle
57
-
58
- // put the needle at 10% of the haystack
59
- *std::next (haystack.begin (), haystack.size () / 10 ) = z;
53
+ Container needle (10 , y);
60
54
61
55
for ([[maybe_unused]] auto _ : st) {
62
56
benchmark::DoNotOptimize (haystack);
@@ -71,33 +65,23 @@ int main(int argc, char** argv) {
71
65
->Arg (8192 );
72
66
};
73
67
// {std,ranges}::find_first_of(it1, it1, it2, it2)
74
- bm.operator ()<std::vector<int >>(" std::find_first_of(vector<int>) (10% haystack, late needle)" , std_find_first_of);
75
- bm.operator ()<std::deque<int >>(" std::find_first_of(deque<int>) (10% haystack, late needle)" , std_find_first_of);
76
- bm.operator ()<std::list<int >>(" std::find_first_of(list<int>) (10% haystack, late needle)" , std_find_first_of);
77
- bm.operator ()<std::vector<int >>(
78
- " rng::find_first_of(vector<int>) (10% haystack, late needle)" , std::ranges::find_first_of);
79
- bm.operator ()<std::deque<int >>(
80
- " rng::find_first_of(deque<int>) (10% haystack, late needle)" , std::ranges::find_first_of);
81
- bm.operator ()<std::list<int >>(
82
- " rng::find_first_of(list<int>) (10% haystack, late needle)" , std::ranges::find_first_of);
68
+ bm.operator ()<std::vector<int >>(" std::find_first_of(vector<int>) (small needle)" , std_find_first_of);
69
+ bm.operator ()<std::deque<int >>(" std::find_first_of(deque<int>) (small needle)" , std_find_first_of);
70
+ bm.operator ()<std::list<int >>(" std::find_first_of(list<int>) (small needle)" , std_find_first_of);
71
+ bm.operator ()<std::vector<int >>(" rng::find_first_of(vector<int>) (small needle)" , std::ranges::find_first_of);
72
+ bm.operator ()<std::deque<int >>(" rng::find_first_of(deque<int>) (small needle)" , std::ranges::find_first_of);
73
+ bm.operator ()<std::list<int >>(" rng::find_first_of(list<int>) (small needle)" , std::ranges::find_first_of);
83
74
84
75
// {std,ranges}::find_first_of(it1, it1, it2, it2, pred)
85
- bm.operator ()<std::vector<int >>(
86
- " std::find_first_of(vector<int>, pred) (25% haystack, late needle)" , std_find_first_of);
87
- bm.operator ()<std::deque<int >>(
88
- " std::find_first_of(deque<int>, pred) (25% haystack, late needle)" , std_find_first_of);
89
- bm.operator ()<std::list<int >>(" std::find_first_of(list<int>, pred) (25% haystack, late needle)" , std_find_first_of);
90
- bm.operator ()<std::vector<int >>(
91
- " rng::find_first_of(vector<int>, pred) (25% haystack, late needle)" , std::ranges::find_first_of);
92
- bm.operator ()<std::deque<int >>(
93
- " rng::find_first_of(deque<int>, pred) (25% haystack, late needle)" , std::ranges::find_first_of);
94
- bm.operator ()<std::list<int >>(
95
- " rng::find_first_of(list<int>, pred) (25% haystack, late needle)" , std::ranges::find_first_of);
76
+ bm.operator ()<std::vector<int >>(" std::find_first_of(vector<int>, pred) (small needle)" , std_find_first_of_pred);
77
+ bm.operator ()<std::deque<int >>(" std::find_first_of(deque<int>, pred) (small needle)" , std_find_first_of_pred);
78
+ bm.operator ()<std::list<int >>(" std::find_first_of(list<int>, pred) (small needle)" , std_find_first_of_pred);
79
+ bm.operator ()<std::vector<int >>(" rng::find_first_of(vector<int>, pred) (small needle)" , ranges_find_first_of_pred);
80
+ bm.operator ()<std::deque<int >>(" rng::find_first_of(deque<int>, pred) (small needle)" , ranges_find_first_of_pred);
81
+ bm.operator ()<std::list<int >>(" rng::find_first_of(list<int>, pred) (small needle)" , ranges_find_first_of_pred);
96
82
}
97
83
98
- // Benchmark {std,ranges}::find_first_of where we have a hit at 90% of the haystack
99
- // but at the beginning of the needle. This measures how quickly we're able to search
100
- // inside the haystack.
84
+ // Special case: the needle is large compared to the haystack, and we find a match early in the haystack.
101
85
{
102
86
auto bm = []<class Container >(std::string name, auto find_first_of) {
103
87
benchmark::RegisterBenchmark (
@@ -107,13 +91,11 @@ int main(int argc, char** argv) {
107
91
using ValueType = typename Container::value_type;
108
92
ValueType x = Generate<ValueType>::random ();
109
93
ValueType y = random_different_from ({x});
110
- ValueType z = random_different_from ({x, y});
111
94
Container haystack (size, x);
112
- Container needle (size, y);
113
- *std::next (needle.begin (), needle.size () / 10 ) = z; // hit at 10% of the needle
95
+ Container needle (size * 10 , y);
114
96
115
- // put the needle at 90 % of the haystack
116
- *std::next (haystack.begin (), ( 9 * haystack.size ()) / 10 ) = z ;
97
+ // put a match at 10 % of the haystack
98
+ *std::next (haystack.begin (), haystack.size () / 10 ) = y ;
117
99
118
100
for ([[maybe_unused]] auto _ : st) {
119
101
benchmark::DoNotOptimize (haystack);
@@ -128,29 +110,20 @@ int main(int argc, char** argv) {
128
110
->Arg (8192 );
129
111
};
130
112
// {std,ranges}::find_first_of(it1, it1, it2, it2)
131
- bm.operator ()<std::vector<int >>(" std::find_first_of(vector<int>) (90% haystack, early needle)" , std_find_first_of);
132
- bm.operator ()<std::deque<int >>(" std::find_first_of(deque<int>) (90% haystack, early needle)" , std_find_first_of);
133
- bm.operator ()<std::list<int >>(" std::find_first_of(list<int>) (90% haystack, early needle)" , std_find_first_of);
134
- bm.operator ()<std::vector<int >>(
135
- " rng::find_first_of(vector<int>) (90% haystack, early needle)" , std::ranges::find_first_of);
136
- bm.operator ()<std::deque<int >>(
137
- " rng::find_first_of(deque<int>) (90% haystack, early needle)" , std::ranges::find_first_of);
138
- bm.operator ()<std::list<int >>(
139
- " rng::find_first_of(list<int>) (90% haystack, early needle)" , std::ranges::find_first_of);
113
+ bm.operator ()<std::vector<int >>(" std::find_first_of(vector<int>) (large needle)" , std_find_first_of);
114
+ bm.operator ()<std::deque<int >>(" std::find_first_of(deque<int>) (large needle)" , std_find_first_of);
115
+ bm.operator ()<std::list<int >>(" std::find_first_of(list<int>) (large needle)" , std_find_first_of);
116
+ bm.operator ()<std::vector<int >>(" rng::find_first_of(vector<int>) (large needle)" , std::ranges::find_first_of);
117
+ bm.operator ()<std::deque<int >>(" rng::find_first_of(deque<int>) (large needle)" , std::ranges::find_first_of);
118
+ bm.operator ()<std::list<int >>(" rng::find_first_of(list<int>) (large needle)" , std::ranges::find_first_of);
140
119
141
120
// {std,ranges}::find_first_of(it1, it1, it2, it2, pred)
142
- bm.operator ()<std::vector<int >>(
143
- " std::find_first_of(vector<int>, pred) (90% haystack, early needle)" , std_find_first_of_pred);
144
- bm.operator ()<std::deque<int >>(
145
- " std::find_first_of(deque<int>, pred) (90% haystack, early needle)" , std_find_first_of_pred);
146
- bm.operator ()<std::list<int >>(
147
- " std::find_first_of(list<int>, pred) (90% haystack, early needle)" , std_find_first_of_pred);
148
- bm.operator ()<std::vector<int >>(
149
- " rng::find_first_of(vector<int>, pred) (90% haystack, early needle)" , ranges_find_first_of_pred);
150
- bm.operator ()<std::deque<int >>(
151
- " rng::find_first_of(deque<int>, pred) (90% haystack, early needle)" , ranges_find_first_of_pred);
152
- bm.operator ()<std::list<int >>(
153
- " rng::find_first_of(list<int>, pred) (90% haystack, early needle)" , ranges_find_first_of_pred);
121
+ bm.operator ()<std::vector<int >>(" std::find_first_of(vector<int>, pred) (large needle)" , std_find_first_of_pred);
122
+ bm.operator ()<std::deque<int >>(" std::find_first_of(deque<int>, pred) (large needle)" , std_find_first_of_pred);
123
+ bm.operator ()<std::list<int >>(" std::find_first_of(list<int>, pred) (large needle)" , std_find_first_of_pred);
124
+ bm.operator ()<std::vector<int >>(" rng::find_first_of(vector<int>, pred) (large needle)" , ranges_find_first_of_pred);
125
+ bm.operator ()<std::deque<int >>(" rng::find_first_of(deque<int>, pred) (large needle)" , ranges_find_first_of_pred);
126
+ bm.operator ()<std::list<int >>(" rng::find_first_of(list<int>, pred) (large needle)" , ranges_find_first_of_pred);
154
127
}
155
128
156
129
benchmark::Initialize (&argc, argv);
0 commit comments