brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.2 KiB · cce2e42 Raw
163 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 <iterator>16#include <list>17#include <vector>18 19#include <benchmark/benchmark.h>20#include "../../GenerateInput.h"21 22int main(int argc, char** argv) {23  // Benchmark ranges::contains_subrange where we never find the needle, which is the24  // worst case.25  {26    auto bm = []<class Container>(std::string name) {27      benchmark::RegisterBenchmark(28          name,29          [](auto& st) {30            std::size_t const size = st.range(0);31            using ValueType        = typename Container::value_type;32            ValueType x            = Generate<ValueType>::random();33            ValueType y            = random_different_from({x});34            Container haystack(size, x);35            std::size_t n = size / 10; // needle size is 10% of the haystack, but we'll never find it36            assert(n > 0);37            Container needle(n, y);38 39            for ([[maybe_unused]] auto _ : st) {40              benchmark::DoNotOptimize(haystack);41              benchmark::DoNotOptimize(needle);42              auto result = std::ranges::contains_subrange(haystack, needle);43              benchmark::DoNotOptimize(result);44            }45          })46          ->Arg(16)47          ->Arg(32)48          ->Arg(50) // non power-of-two49          ->Arg(8192)50          ->Arg(1 << 20);51    };52    bm.operator()<std::vector<int>>("rng::contains_subrange(vector<int>) (process all)");53    bm.operator()<std::deque<int>>("rng::contains_subrange(deque<int>) (process all)");54    bm.operator()<std::list<int>>("rng::contains_subrange(list<int>) (process all)");55  }56 57  // Benchmark ranges::contains_subrange where we intersperse "near matches" inside the haystack.58  {59    auto bm = []<class Container>(std::string name) {60      benchmark::RegisterBenchmark(61          name,62          [](auto& st) {63            std::size_t const size = st.range(0);64            using ValueType        = typename Container::value_type;65            ValueType x            = Generate<ValueType>::random();66            ValueType y            = random_different_from({x});67            Container haystack(size, x);68            std::size_t n = size / 10; // needle size is 10% of the haystack, but we'll never find it69            assert(n > 0);70            Container needle(n, y);71 72            // intersperse near-matches inside the haystack73            {74              auto first = haystack.begin();75              for (int i = 0; i != 10; ++i) {76                first = std::copy_n(needle.begin(), n - 1, first);77                ++first; // this causes the subsequence not to match because it has length n-178              }79            }80 81            for ([[maybe_unused]] auto _ : st) {82              benchmark::DoNotOptimize(haystack);83              benchmark::DoNotOptimize(needle);84              auto result = std::ranges::contains_subrange(haystack, needle);85              benchmark::DoNotOptimize(result);86            }87          })88          ->Arg(1000) // non power-of-two89          ->Arg(1024)90          ->Arg(8192);91    };92    bm.operator()<std::vector<int>>("rng::contains_subrange(vector<int>) (near matches)");93    bm.operator()<std::deque<int>>("rng::contains_subrange(deque<int>) (near matches)");94    bm.operator()<std::list<int>>("rng::contains_subrange(list<int>) (near matches)");95  }96 97  // Special case: the two ranges are the same length (and they are equal, which is the worst case).98  {99    auto bm = []<class Container>(std::string name) {100      benchmark::RegisterBenchmark(101          name,102          [](auto& st) {103            std::size_t const size = st.range(0);104            using ValueType        = typename Container::value_type;105            ValueType x            = Generate<ValueType>::random();106            Container haystack(size, x);107            Container needle(size, x);108 109            for ([[maybe_unused]] auto _ : st) {110              benchmark::DoNotOptimize(haystack);111              benchmark::DoNotOptimize(needle);112              auto result = std::ranges::contains_subrange(haystack, needle);113              benchmark::DoNotOptimize(result);114            }115          })116          ->Arg(16)117          ->Arg(32)118          ->Arg(50) // non power-of-two119          ->Arg(8192)120          ->Arg(1 << 20);121    };122    bm.operator()<std::vector<int>>("rng::contains_subrange(vector<int>) (same length)");123    bm.operator()<std::deque<int>>("rng::contains_subrange(deque<int>) (same length)");124    bm.operator()<std::list<int>>("rng::contains_subrange(list<int>) (same length)");125  }126 127  // Special case: the needle contains a single element (which we never find, i.e. the worst case).128  {129    auto bm = []<class Container>(std::string name) {130      benchmark::RegisterBenchmark(131          name,132          [](auto& st) {133            std::size_t const size = st.range(0);134            using ValueType        = typename Container::value_type;135            ValueType x            = Generate<ValueType>::random();136            ValueType y            = random_different_from({x});137            Container haystack(size, x);138            Container needle(1, y);139 140            for ([[maybe_unused]] auto _ : st) {141              benchmark::DoNotOptimize(haystack);142              benchmark::DoNotOptimize(needle);143              auto result = std::ranges::contains_subrange(haystack, needle);144              benchmark::DoNotOptimize(result);145            }146          })147          ->Arg(16)148          ->Arg(32)149          ->Arg(50) // non power-of-two150          ->Arg(8192)151          ->Arg(1 << 20);152    };153    bm.operator()<std::vector<int>>("rng::contains_subrange(vector<int>) (single element)");154    bm.operator()<std::deque<int>>("rng::contains_subrange(deque<int>) (single element)");155    bm.operator()<std::list<int>>("rng::contains_subrange(list<int>) (single element)");156  }157 158  benchmark::Initialize(&argc, argv);159  benchmark::RunSpecifiedBenchmarks();160  benchmark::Shutdown();161  return 0;162}163