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// UNSUPPORTED: c++03, c++11, c++14, c++17
10
11#include <algorithm>
12#include <cstddef>
13#include <deque>
14#include <list>
15#include <string>
16#include <vector>
17
18#include <benchmark/benchmark.h>
19#include "../../GenerateInput.h"
20
21int main(int argc, char** argv) {
22 auto std_count = [](auto first, auto last, auto const& value) { return std::count(first, last, value); };
23 auto std_count_if = [](auto first, auto last, auto const& value) {
24 return std::count_if(first, last, [&](auto element) {
25 benchmark::DoNotOptimize(element);
26 return element == value;
27 });
28 };
29
30 auto ranges_count = [](auto first, auto last, auto const& value) { return std::ranges::count(first, last, value); };
31 auto ranges_count_if = [](auto first, auto last, auto const& value) {
32 return std::ranges::count_if(first, last, [&](auto element) {
33 benchmark::DoNotOptimize(element);
34 return element == value;
35 });
36 };
37
38 // Benchmark {std,ranges}::{count,count_if} on a sequence where every other element is counted.
39 {
40 auto bm = []<class Container>(std::string name, auto count) {
41 benchmark::RegisterBenchmark(
42 name,
43 [count](auto& st) {
44 std::size_t const size = st.range(0);
45 using ValueType = typename Container::value_type;
46 ValueType x = Generate<ValueType>::random();
47 ValueType y = random_different_from({x});
48 Container c;
49 for (std::size_t i = 0; i != size; ++i) {
50 c.push_back(i % 2 == 0 ? x : y);
51 }
52
53 for ([[maybe_unused]] auto _ : st) {
54 benchmark::DoNotOptimize(c);
55 benchmark::DoNotOptimize(x);
56 auto result = count(c.begin(), c.end(), x);
57 benchmark::DoNotOptimize(result);
58 }
59 })
60 ->Arg(8)
61 ->Arg(1024)
62 ->Arg(8192)
63 ->Arg(1 << 20);
64 };
65
66 // count
67 bm.operator()<std::vector<int>>(name: "std::count(vector<int>) (every other)", count: std_count);
68 bm.operator()<std::deque<int>>(name: "std::count(deque<int>) (every other)", count: std_count);
69 bm.operator()<std::list<int>>(name: "std::count(list<int>) (every other)", count: std_count);
70 bm.operator()<std::vector<int>>(name: "rng::count(vector<int>) (every other)", count: ranges_count);
71 bm.operator()<std::deque<int>>(name: "rng::count(deque<int>) (every other)", count: ranges_count);
72 bm.operator()<std::list<int>>(name: "rng::count(list<int>) (every other)", count: ranges_count);
73
74 // count_if
75 bm.operator()<std::vector<int>>(name: "std::count_if(vector<int>) (every other)", count: std_count_if);
76 bm.operator()<std::deque<int>>(name: "std::count_if(deque<int>) (every other)", count: std_count_if);
77 bm.operator()<std::list<int>>(name: "std::count_if(list<int>) (every other)", count: std_count_if);
78 bm.operator()<std::vector<int>>(name: "rng::count_if(vector<int>) (every other)", count: ranges_count_if);
79 bm.operator()<std::deque<int>>(name: "rng::count_if(deque<int>) (every other)", count: ranges_count_if);
80 bm.operator()<std::list<int>>(name: "rng::count_if(list<int>) (every other)", count: ranges_count_if);
81 }
82
83 // Benchmark {std,ranges}::count(vector<bool>)
84 {
85 auto bm = [](std::string name, auto count) {
86 benchmark::RegisterBenchmark(
87 name,
88 [count](auto& st) {
89 std::size_t const size = st.range(0);
90 std::vector<bool> c(size, false);
91
92 for ([[maybe_unused]] auto _ : st) {
93 benchmark::DoNotOptimize(c);
94 auto result = count(c.begin(), c.end(), true);
95 benchmark::DoNotOptimize(result);
96 }
97 })
98 ->Arg(1000) // non power-of-two
99 ->Arg(1024)
100 ->Arg(8192)
101 ->Arg(1 << 20);
102 };
103 bm.operator()(name: "std::count(vector<bool>)", count: std_count);
104 bm.operator()(name: "rng::count(vector<bool>)", count: ranges_count);
105 }
106
107 benchmark::Initialize(&argc, argv);
108 benchmark::RunSpecifiedBenchmarks();
109 benchmark::Shutdown();
110 return 0;
111}
112

source code of libcxx/test/benchmarks/algorithms/nonmodifying/count.bench.cpp