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 <array>
13#include <cstddef>
14#include <deque>
15#include <string>
16#include <vector>
17
18#include "benchmark/benchmark.h"
19#include "common.h"
20
21int main(int argc, char** argv) {
22 auto std_sort = [](auto first, auto last) { return std::sort(first, last); };
23
24 // Benchmark {std,ranges}::sort on various types of data
25 //
26 // We perform this benchmark in a batch because we need to restore the
27 // state of the container after the operation.
28 //
29 // Also note that we intentionally don't benchmark the predicated version of the algorithm
30 // because that makes the benchmark run too slowly.
31 {
32 auto bm = []<class Container>(std::string name, auto sort, auto generate_data) {
33 benchmark::RegisterBenchmark(
34 name,
35 [sort, generate_data](auto& st) {
36 std::size_t const size = st.range(0);
37 constexpr std::size_t BatchSize = 32;
38 using ValueType = typename Container::value_type;
39 std::vector<ValueType> data = generate_data(size);
40 std::array<Container, BatchSize> c;
41 std::fill_n(c.begin(), BatchSize, Container(data.begin(), data.end()));
42
43 while (st.KeepRunningBatch(BatchSize)) {
44 for (std::size_t i = 0; i != BatchSize; ++i) {
45 benchmark::DoNotOptimize(c[i]);
46 sort(c[i].begin(), c[i].end());
47 benchmark::DoNotOptimize(c[i]);
48 }
49
50 st.PauseTiming();
51 for (std::size_t i = 0; i != BatchSize; ++i) {
52 std::copy(data.begin(), data.end(), c[i].begin());
53 }
54 st.ResumeTiming();
55 }
56 })
57 ->Arg(8)
58 ->Arg(1024)
59 ->Arg(8192);
60 };
61
62 auto register_bm = [&](auto generate, std::string variant) {
63 auto gen2 = [generate](auto size) {
64 std::vector<int> data = generate(size);
65 std::vector<support::NonIntegral> real_data(data.begin(), data.end());
66 return real_data;
67 };
68 auto name = [variant](std::string op) { return op + " (" + variant + ")"; };
69 bm.operator()<std::vector<int>>(name("std::sort(vector<int>)"), std_sort, generate);
70 bm.operator()<std::vector<support::NonIntegral>>(name("std::sort(vector<NonIntegral>)"), std_sort, gen2);
71 bm.operator()<std::deque<int>>(name("std::sort(deque<int>)"), std_sort, generate);
72
73 bm.operator()<std::vector<int>>(name("rng::sort(vector<int>)"), std::ranges::sort, generate);
74 bm.operator()<std::vector<support::NonIntegral>>(name("rng::sort(vector<NonIntegral>)"), std::ranges::sort, gen2);
75 bm.operator()<std::deque<int>>(name("rng::sort(deque<int>)"), std::ranges::sort, generate);
76 };
77
78 register_bm(support::quicksort_adversarial_data<int>, "qsort adversarial");
79 register_bm(support::ascending_sorted_data<int>, "ascending");
80 register_bm(support::descending_sorted_data<int>, "descending");
81 register_bm(support::pipe_organ_data<int>, "pipe-organ");
82 register_bm(support::heap_data<int>, "heap");
83 register_bm(support::shuffled_data<int>, "shuffled");
84 register_bm(support::single_element_data<int>, "repeated");
85 }
86
87 benchmark::Initialize(&argc, argv);
88 benchmark::RunSpecifiedBenchmarks();
89 benchmark::Shutdown();
90 return 0;
91}
92

source code of libcxx/test/benchmarks/algorithms/sorting/sort.bench.cpp