brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.8 KiB · 2b98d16 Raw
75 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++1710 11#include <algorithm>12#include <cstddef>13#include <deque>14#include <iterator>15#include <list>16#include <string>17#include <vector>18 19#include "benchmark/benchmark.h"20#include "../../GenerateInput.h"21 22auto compute_median(auto first, auto last) {23  std::vector v(first, last);24  auto middle = v.begin() + v.size() / 2;25  std::nth_element(v.begin(), middle, v.end());26  return *middle;27}28 29int main(int argc, char** argv) {30  auto std_partition_point = [](auto first, auto last, auto pred) { return std::partition_point(first, last, pred); };31 32  auto bm = []<class Container>(std::string name, auto partition_point) {33    benchmark::RegisterBenchmark(34        name,35        [partition_point](auto& st) {36          std::size_t const size = st.range(0);37          using ValueType        = typename Container::value_type;38          Container c;39          std::generate_n(std::back_inserter(c), size, [] { return Generate<ValueType>::random(); });40 41          // Partition the container in two equally-sized halves. Based on experimentation, the running42          // time of the algorithm doesn't change much depending on the size of the halves.43          ValueType median = compute_median(c.begin(), c.end());44          auto pred        = [median](auto const& element) { return element < median; };45          std::partition(c.begin(), c.end(), pred);46          assert(std::is_partitioned(c.begin(), c.end(), pred));47 48          for ([[maybe_unused]] auto _ : st) {49            benchmark::DoNotOptimize(c);50            auto result = partition_point(c.begin(), c.end(), pred);51            benchmark::DoNotOptimize(result);52          }53        })54        ->Arg(32)55        ->Arg(50) // non power-of-two56        ->Arg(1024)57        ->Arg(8192);58  };59 60  // std::partition_point61  bm.operator()<std::vector<int>>("std::partition_point(vector<int>)", std_partition_point);62  bm.operator()<std::deque<int>>("std::partition_point(deque<int>)", std_partition_point);63  bm.operator()<std::list<int>>("std::partition_point(list<int>)", std_partition_point);64 65  // ranges::partition_point66  bm.operator()<std::vector<int>>("rng::partition_point(vector<int>)", std::ranges::partition_point);67  bm.operator()<std::deque<int>>("rng::partition_point(deque<int>)", std::ranges::partition_point);68  bm.operator()<std::list<int>>("rng::partition_point(list<int>)", std::ranges::partition_point);69 70  benchmark::Initialize(&argc, argv);71  benchmark::RunSpecifiedBenchmarks();72  benchmark::Shutdown();73  return 0;74}75