119 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++14, c++17, c++2010 11#include <algorithm>12#include <cassert>13#include <cstddef>14#include <deque>15#include <forward_list>16#include <list>17#include <string>18#include <vector>19 20#include <benchmark/benchmark.h>21#include "../../GenerateInput.h"22 23int main(int argc, char** argv) {24 auto ranges_ends_with_pred = [](auto first1, auto last1, auto first2, auto last2) {25 return std::ranges::ends_with(first1, last1, first2, last2, [](auto x, auto y) {26 benchmark::DoNotOptimize(x);27 benchmark::DoNotOptimize(y);28 return x == y;29 });30 };31 32 // Benchmark ranges::ends_with where we find the mismatching element at the very end.33 {34 auto bm = []<class Container>(std::string name, auto ends_with) {35 benchmark::RegisterBenchmark(36 name,37 [ends_with](auto& st) {38 std::size_t const size = st.range(0);39 using ValueType = typename Container::value_type;40 ValueType x = Generate<ValueType>::random();41 ValueType y = random_different_from({x});42 Container c1(size, x);43 Container c2(size, x);44 assert(size != 0);45 *std::next(c2.begin(), size - 1) = y; // set last element to y46 47 for ([[maybe_unused]] auto _ : st) {48 benchmark::DoNotOptimize(c1);49 benchmark::DoNotOptimize(c2);50 auto result = ends_with(c1.begin(), c1.end(), c2.begin(), c2.end());51 benchmark::DoNotOptimize(result);52 }53 })54 ->Arg(8)55 ->Arg(50) // non power-of-two56 ->Arg(1024)57 ->Arg(8192)58 ->Arg(1 << 20);59 };60 bm.operator()<std::vector<int>>("rng::ends_with(vector<int>) (mismatch at end)", std::ranges::ends_with);61 bm.operator()<std::deque<int>>("rng::ends_with(deque<int>) (mismatch at end)", std::ranges::ends_with);62 bm.operator()<std::list<int>>("rng::ends_with(list<int>) (mismatch at end)", std::ranges::ends_with);63 bm.operator()<std::forward_list<int>>(64 "rng::ends_with(forward_list<int>) (mismatch at end)", std::ranges::ends_with);65 66 bm.operator()<std::vector<int>>("rng::ends_with(vector<int>, pred) (mismatch at end)", ranges_ends_with_pred);67 bm.operator()<std::deque<int>>("rng::ends_with(deque<int>, pred) (mismatch at end)", ranges_ends_with_pred);68 bm.operator()<std::list<int>>("rng::ends_with(list<int>, pred) (mismatch at end)", ranges_ends_with_pred);69 bm.operator()<std::forward_list<int>>(70 "rng::ends_with(forward_list<int>, pred) (mismatch at end)", ranges_ends_with_pred);71 }72 73 // Benchmark ranges::ends_with where we find the mismatching element at the very beginning.74 {75 auto bm = []<class Container>(std::string name, auto ends_with) {76 benchmark::RegisterBenchmark(77 name,78 [ends_with](auto& st) {79 std::size_t const size = st.range(0);80 using ValueType = typename Container::value_type;81 ValueType x = Generate<ValueType>::random();82 ValueType y = random_different_from({x});83 Container c1(size, x);84 Container c2(size, x);85 assert(size != 0);86 c2.front() = y;87 88 for ([[maybe_unused]] auto _ : st) {89 benchmark::DoNotOptimize(c1);90 benchmark::DoNotOptimize(c2);91 auto result = ends_with(c1.begin(), c1.end(), c2.begin(), c2.end());92 benchmark::DoNotOptimize(result);93 }94 })95 ->Arg(8)96 ->Arg(50) // non power-of-two97 ->Arg(1024)98 ->Arg(8192)99 ->Arg(1 << 20);100 };101 bm.operator()<std::vector<int>>("rng::ends_with(vector<int>) (mismatch at start)", std::ranges::ends_with);102 bm.operator()<std::deque<int>>("rng::ends_with(deque<int>) (mismatch at start)", std::ranges::ends_with);103 bm.operator()<std::list<int>>("rng::ends_with(list<int>) (mismatch at start)", std::ranges::ends_with);104 bm.operator()<std::forward_list<int>>(105 "rng::ends_with(forward_list<int>) (mismatch at start)", std::ranges::ends_with);106 107 bm.operator()<std::vector<int>>("rng::ends_with(vector<int>, pred) (mismatch at start)", ranges_ends_with_pred);108 bm.operator()<std::deque<int>>("rng::ends_with(deque<int>, pred) (mismatch at start)", ranges_ends_with_pred);109 bm.operator()<std::list<int>>("rng::ends_with(list<int>, pred) (mismatch at start)", ranges_ends_with_pred);110 bm.operator()<std::forward_list<int>>(111 "rng::ends_with(forward_list<int>, pred) (mismatch at start)", ranges_ends_with_pred);112 }113 114 benchmark::Initialize(&argc, argv);115 benchmark::RunSpecifiedBenchmarks();116 benchmark::Shutdown();117 return 0;118}119