@@ -38,9 +38,8 @@ int main(int argc, char** argv) {
3838 });
3939 };
4040
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).
4443 {
4544 auto bm = []<class Container >(std::string name, auto find_first_of) {
4645 benchmark::RegisterBenchmark (
@@ -50,13 +49,8 @@ int main(int argc, char** argv) {
5049 using ValueType = typename Container::value_type;
5150 ValueType x = Generate<ValueType>::random ();
5251 ValueType y = random_different_from ({x});
53- ValueType z = random_different_from ({x, y});
5452 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);
6054
6155 for ([[maybe_unused]] auto _ : st) {
6256 benchmark::DoNotOptimize (haystack);
@@ -71,33 +65,23 @@ int main(int argc, char** argv) {
7165 ->Arg (8192 );
7266 };
7367 // {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);
8374
8475 // {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);
9682 }
9783
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.
10185 {
10286 auto bm = []<class Container >(std::string name, auto find_first_of) {
10387 benchmark::RegisterBenchmark (
@@ -107,13 +91,11 @@ int main(int argc, char** argv) {
10791 using ValueType = typename Container::value_type;
10892 ValueType x = Generate<ValueType>::random ();
10993 ValueType y = random_different_from ({x});
110- ValueType z = random_different_from ({x, y});
11194 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);
11496
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 ;
11799
118100 for ([[maybe_unused]] auto _ : st) {
119101 benchmark::DoNotOptimize (haystack);
@@ -128,29 +110,20 @@ int main(int argc, char** argv) {
128110 ->Arg (8192 );
129111 };
130112 // {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);
140119
141120 // {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);
154127 }
155128
156129 benchmark::Initialize (&argc, argv);
0 commit comments