1//===----------------------------------------------------------------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
9#include <algorithm>
10#include <benchmark/benchmark.h>
11#include <iterator>
12
13#include "test_iterators.h"
14#include <vector>
15
16static void bm_ends_with_contiguous_iter(benchmark::State& state) {
17 std::vector<int> a(state.range(), 1);
18 std::vector<int> p(state.range(), 1);
19
20 for (auto _ : state) {
21 benchmark::DoNotOptimize(a);
22 benchmark::DoNotOptimize(p);
23
24 auto begin1 = contiguous_iterator(a.data());
25 auto end1 = contiguous_iterator(a.data() + a.size());
26 auto begin2 = contiguous_iterator(p.data());
27 auto end2 = contiguous_iterator(p.data() + p.size());
28
29 benchmark::DoNotOptimize(std::ranges::ends_with(begin1, end1, begin2, end2));
30 }
31}
32BENCHMARK(bm_ends_with_contiguous_iter)->RangeMultiplier(16)->Range(16, 16 << 20);
33
34static void bm_ends_with_random_iter(benchmark::State& state) {
35 std::vector<int> a(state.range(), 1);
36 std::vector<int> p(state.range(), 1);
37
38 for (auto _ : state) {
39 benchmark::DoNotOptimize(a);
40 benchmark::DoNotOptimize(p);
41
42 auto begin1 = random_access_iterator(a.begin());
43 auto end1 = random_access_iterator(a.end());
44 auto begin2 = random_access_iterator(p.begin());
45 auto end2 = random_access_iterator(p.end());
46
47 benchmark::DoNotOptimize(std::ranges::ends_with(begin1, end1, begin2, end2));
48 }
49}
50BENCHMARK(bm_ends_with_random_iter)->RangeMultiplier(16)->Range(16, 16 << 20);
51
52static void bm_ends_with_bidirectional_iter(benchmark::State& state) {
53 std::vector<int> a(state.range(), 1);
54 std::vector<int> p(state.range(), 1);
55
56 for (auto _ : state) {
57 benchmark::DoNotOptimize(a);
58 benchmark::DoNotOptimize(p);
59
60 auto begin1 = bidirectional_iterator(a.begin());
61 auto end1 = bidirectional_iterator(a.end());
62 auto begin2 = bidirectional_iterator(p.begin());
63 auto end2 = bidirectional_iterator(p.end());
64
65 benchmark::DoNotOptimize(std::ranges::ends_with(begin1, end1, begin2, end2));
66 }
67}
68BENCHMARK(bm_ends_with_bidirectional_iter)->RangeMultiplier(16)->Range(16, 16 << 20);
69
70static void bm_ends_with_forward_iter(benchmark::State& state) {
71 std::vector<int> a(state.range(), 1);
72 std::vector<int> p(state.range(), 1);
73
74 for (auto _ : state) {
75 benchmark::DoNotOptimize(a);
76 benchmark::DoNotOptimize(p);
77
78 auto begin1 = forward_iterator(a.begin());
79 auto end1 = forward_iterator(a.end());
80 auto begin2 = forward_iterator(p.begin());
81 auto end2 = forward_iterator(p.end());
82
83 benchmark::DoNotOptimize(std::ranges::ends_with(begin1, end1, begin2, end2));
84 }
85}
86BENCHMARK(bm_ends_with_forward_iter)->RangeMultiplier(16)->Range(16, 16 << 20);
87
88static void bm_ends_with_forward_iter_with_size_optimization(benchmark::State& state) {
89 std::vector<int> a(state.range(), 1);
90 std::vector<int> p(state.range(), 1);
91 p.push_back(2);
92
93 for (auto _ : state) {
94 benchmark::DoNotOptimize(a);
95 benchmark::DoNotOptimize(p);
96
97 auto begin1 = forward_iterator(a.begin());
98 auto end1 = forward_iterator(a.end());
99 auto begin2 = forward_iterator(p.begin());
100 auto end2 = forward_iterator(p.end());
101
102 benchmark::DoNotOptimize(std::ranges::ends_with(begin1, end1, begin2, end2));
103 }
104}
105BENCHMARK(bm_ends_with_forward_iter_with_size_optimization)->RangeMultiplier(16)->Range(16, 16 << 20);
106
107BENCHMARK_MAIN();
108