summaryrefslogtreecommitdiff
path: root/libcxx/benchmarks
diff options
context:
space:
mode:
authorNikolas Klauser <nikolasklauser@berlin.de>2022-05-19 12:50:02 +0200
committerNikolas Klauser <nikolasklauser@berlin.de>2022-05-19 16:13:52 +0200
commitf94a4476791873a4af1986abcd13c18991a599ee (patch)
tree8e06230c33bce8e839d5b730b21ed11e4b53a62b /libcxx/benchmarks
parentb2f9bde2e0e0fb9a26c2809aed17213e0920cf0f (diff)
downloadllvm-f94a4476791873a4af1986abcd13c18991a599ee.tar.gz
[libc++] Granularize algorithm benchmarks
Reviewed By: ldionne, #libc Spies: libcxx-commits, mgorny, mgrang Differential Revision: https://reviews.llvm.org/D124740
Diffstat (limited to 'libcxx/benchmarks')
-rw-r--r--libcxx/benchmarks/CMakeLists.txt39
-rw-r--r--libcxx/benchmarks/algorithms/common.h (renamed from libcxx/benchmarks/algorithms.bench.cpp)198
-rw-r--r--libcxx/benchmarks/algorithms/make_heap.bench.cpp37
-rw-r--r--libcxx/benchmarks/algorithms/make_heap_then_sort_heap.bench.cpp39
-rw-r--r--libcxx/benchmarks/algorithms/min_max_element.bench.cpp36
-rw-r--r--libcxx/benchmarks/algorithms/pop_heap.bench.cpp39
-rw-r--r--libcxx/benchmarks/algorithms/push_heap.bench.cpp42
-rw-r--r--libcxx/benchmarks/algorithms/sort.bench.cpp39
-rw-r--r--libcxx/benchmarks/algorithms/sort_heap.bench.cpp36
-rw-r--r--libcxx/benchmarks/algorithms/stable_sort.bench.cpp39
10 files changed, 365 insertions, 179 deletions
diff --git a/libcxx/benchmarks/CMakeLists.txt b/libcxx/benchmarks/CMakeLists.txt
index e5f96aa88bd1..71b73158f467 100644
--- a/libcxx/benchmarks/CMakeLists.txt
+++ b/libcxx/benchmarks/CMakeLists.txt
@@ -159,10 +159,41 @@ endfunction()
#==============================================================================
# Register Benchmark tests
#==============================================================================
-file(GLOB BENCHMARK_TESTS "*.bench.cpp")
+set(BENCHMARK_TESTS
+ algorithms/make_heap_then_sort_heap.bench.cpp
+ algorithms/make_heap.bench.cpp
+ algorithms/min_max_element.bench.cpp
+ algorithms/pop_heap.bench.cpp
+ algorithms/push_heap.bench.cpp
+ algorithms/sort_heap.bench.cpp
+ algorithms/stable_sort.bench.cpp
+ algorithms.partition_point.bench.cpp
+ allocation.bench.cpp
+ deque.bench.cpp
+ filesystem.bench.cpp
+ function.bench.cpp
+ map.bench.cpp
+ ordered_set.bench.cpp
+ string.bench.cpp
+ stringstream.bench.cpp
+ to_chars.bench.cpp
+ unordered_set_operations.bench.cpp
+ util_smartptr.bench.cpp
+ variant_visit_1.bench.cpp
+ variant_visit_2.bench.cpp
+ variant_visit_3.bench.cpp
+ vector_operations.bench.cpp
+ )
-if (NOT LIBCXX_ENABLE_INCOMPLETE_FEATURES)
- list(FILTER BENCHMARK_TESTS EXCLUDE REGEX "(format_to_n|format_to|format|formatted_size|formatter_float|std_format_spec_string_unicode).bench.cpp")
+if (LIBCXX_ENABLE_INCOMPLETE_FEATURES)
+ set(BENCHMARK_TESTS
+ ${BENCHMARK_TESTS}
+ format_to_n.bench.cpp
+ format_to.bench.cpp
+ format.bench.cpp
+ formatted_size.bench.cpp
+ formatter_float.bench.cpp
+ std_format_spec_string_unicode.bench.cpp)
endif()
foreach(test_path ${BENCHMARK_TESTS})
@@ -173,7 +204,7 @@ foreach(test_path ${BENCHMARK_TESTS})
# Only report the adding of the benchmark once.
set(${test_name}_REPORTED ON CACHE INTERNAL "")
endif()
- add_benchmark_test(${test_name} ${test_file})
+ add_benchmark_test(${test_name} ${test_path})
endforeach()
if (LIBCXX_INCLUDE_TESTS)
diff --git a/libcxx/benchmarks/algorithms.bench.cpp b/libcxx/benchmarks/algorithms/common.h
index 71f2d2c6e7bb..9a05a2fedbe6 100644
--- a/libcxx/benchmarks/algorithms.bench.cpp
+++ b/libcxx/benchmarks/algorithms/common.h
@@ -1,18 +1,21 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LIBCXX_ALGORITHMS_COMMON_H
+#define LIBCXX_ALGORITHMS_COMMON_H
#include <algorithm>
-#include <cstdint>
-#include <map>
-#include <random>
-#include <string>
-#include <utility>
+#include <numeric>
+#include <tuple>
#include <vector>
-#include "CartesianBenchmarks.h"
-#include "GenerateInput.h"
-#include "benchmark/benchmark.h"
-#include "test_macros.h"
-
-namespace {
+#include "../CartesianBenchmarks.h"
+#include "../GenerateInput.h"
enum class ValueType { Uint32, Uint64, Pair, Tuple, String, Float };
struct AllValueTypes : EnumValuesAsTuple<AllValueTypes, ValueType, 6> {
@@ -54,9 +57,9 @@ void fillAdversarialQuickSortInput(T& V, size_t N) {
assert(N > 0);
// If an element is equal to gas, it indicates that the value of the element
// is still to be decided and may change over the course of time.
- const int gas = N - 1;
+ const unsigned int gas = N - 1;
V.resize(N);
- for (int i = 0; i < N; ++i) {
+ for (unsigned int i = 0; i < N; ++i) {
V[i] = gas;
}
// Candidate for the pivot position.
@@ -134,7 +137,7 @@ void fillValues(std::vector<std::tuple<T1, T2, T3> >& V, size_t N, Order O) {
}
}
-void fillValues(std::vector<std::string>& V, size_t N, Order O) {
+inline void fillValues(std::vector<std::string>& V, size_t N, Order O) {
if (O == Order::SingleElement) {
V.resize(N, getRandomString(64));
} else {
@@ -228,169 +231,14 @@ void runOpOnCopies(benchmark::State& state, size_t Quantity, Order O,
}
}
-template <class ValueType, class Order>
-struct Sort {
- size_t Quantity;
-
- void run(benchmark::State& state) const {
- runOpOnCopies<ValueType>(
- state, Quantity, Order(), BatchSize::CountElements,
- [](auto& Copy) { std::sort(Copy.begin(), Copy.end()); });
- }
-
- bool skip() const { return Order() == ::Order::Heap; }
-
- std::string name() const {
- return "BM_Sort" + ValueType::name() + Order::name() + "_" +
- std::to_string(Quantity);
- };
-};
-
-template <class ValueType, class Order>
-struct StableSort {
- size_t Quantity;
-
- void run(benchmark::State& state) const {
- runOpOnCopies<ValueType>(
- state, Quantity, Order(), BatchSize::CountElements,
- [](auto& Copy) { std::stable_sort(Copy.begin(), Copy.end()); });
- }
-
- bool skip() const { return Order() == ::Order::Heap; }
-
- std::string name() const {
- return "BM_StableSort" + ValueType::name() + Order::name() + "_" +
- std::to_string(Quantity);
- };
-};
-
-template <class ValueType, class Order>
-struct MakeHeap {
- size_t Quantity;
-
- void run(benchmark::State& state) const {
- runOpOnCopies<ValueType>(
- state, Quantity, Order(), BatchSize::CountElements,
- [](auto& Copy) { std::make_heap(Copy.begin(), Copy.end()); });
- }
-
- std::string name() const {
- return "BM_MakeHeap" + ValueType::name() + Order::name() + "_" +
- std::to_string(Quantity);
- };
-};
-
-template <class ValueType>
-struct SortHeap {
- size_t Quantity;
-
- void run(benchmark::State& state) const {
- runOpOnCopies<ValueType>(
- state, Quantity, Order::Heap, BatchSize::CountElements,
- [](auto& Copy) { std::sort_heap(Copy.begin(), Copy.end()); });
- }
-
- std::string name() const {
- return "BM_SortHeap" + ValueType::name() + "_" + std::to_string(Quantity);
- };
-};
-
-template <class ValueType, class Order>
-struct MakeThenSortHeap {
- size_t Quantity;
-
- void run(benchmark::State& state) const {
- runOpOnCopies<ValueType>(state, Quantity, Order(), BatchSize::CountElements,
- [](auto& Copy) {
- std::make_heap(Copy.begin(), Copy.end());
- std::sort_heap(Copy.begin(), Copy.end());
- });
- }
-
- std::string name() const {
- return "BM_MakeThenSortHeap" + ValueType::name() + Order::name() + "_" +
- std::to_string(Quantity);
- };
-};
-
-template <class ValueType, class Order>
-struct PushHeap {
- size_t Quantity;
-
- void run(benchmark::State& state) const {
- runOpOnCopies<ValueType>(
- state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
- for (auto I = Copy.begin(), E = Copy.end(); I != E; ++I) {
- std::push_heap(Copy.begin(), I + 1);
- }
- });
- }
-
- bool skip() const { return Order() == ::Order::Heap; }
-
- std::string name() const {
- return "BM_PushHeap" + ValueType::name() + Order::name() + "_" +
- std::to_string(Quantity);
- };
-};
-
-template <class ValueType>
-struct PopHeap {
- size_t Quantity;
-
- void run(benchmark::State& state) const {
- runOpOnCopies<ValueType>(
- state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
- for (auto B = Copy.begin(), I = Copy.end(); I != B; --I) {
- std::pop_heap(B, I);
- }
- });
- }
- std::string name() const {
- return "BM_PopHeap" + ValueType::name() + "_" + std::to_string(Quantity);
- };
-};
-
-template <class ValueType, class Order>
-struct MinMaxElement {
- size_t Quantity;
-
- void run(benchmark::State& state) const {
- runOpOnCopies<ValueType>(state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
- benchmark::DoNotOptimize(std::minmax_element(Copy.begin(), Copy.end()));
- });
- }
-
- std::string name() const {
- return "BM_MinMaxElement" + ValueType::name() + Order::name() + "_" + std::to_string(Quantity);
- }
-};
-
-} // namespace
-
-int main(int argc, char** argv) {
- benchmark::Initialize(&argc, argv);
- if (benchmark::ReportUnrecognizedArguments(argc, argv))
- return 1;
-
- const std::vector<size_t> Quantities = {1 << 0, 1 << 2, 1 << 4, 1 << 6,
- 1 << 8, 1 << 10, 1 << 14,
+const std::vector<size_t> Quantities = {1 << 0, 1 << 2, 1 << 4, 1 << 6,
+ 1 << 8, 1 << 10, 1 << 14,
// Running each benchmark in parallel consumes too much memory with MSAN
// and can lead to the test process being killed.
#if !TEST_HAS_FEATURE(memory_sanitizer)
- 1 << 18
+ 1 << 18
#endif
- };
- makeCartesianProductBenchmark<Sort, AllValueTypes, AllOrders>(Quantities);
- makeCartesianProductBenchmark<StableSort, AllValueTypes, AllOrders>(
- Quantities);
- makeCartesianProductBenchmark<MakeHeap, AllValueTypes, AllOrders>(Quantities);
- makeCartesianProductBenchmark<SortHeap, AllValueTypes>(Quantities);
- makeCartesianProductBenchmark<MakeThenSortHeap, AllValueTypes, AllOrders>(
- Quantities);
- makeCartesianProductBenchmark<PushHeap, AllValueTypes, AllOrders>(Quantities);
- makeCartesianProductBenchmark<PopHeap, AllValueTypes>(Quantities);
- makeCartesianProductBenchmark<MinMaxElement, AllValueTypes, AllOrders>(Quantities);
- benchmark::RunSpecifiedBenchmarks();
-}
+};
+
+#endif // LIBCXX_ALGORITHMS_COMMON_H
diff --git a/libcxx/benchmarks/algorithms/make_heap.bench.cpp b/libcxx/benchmarks/algorithms/make_heap.bench.cpp
new file mode 100644
index 000000000000..e2caf84d137a
--- /dev/null
+++ b/libcxx/benchmarks/algorithms/make_heap.bench.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+
+#include "common.h"
+
+namespace {
+template <class ValueType, class Order>
+struct MakeHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(
+ state, Quantity, Order(), BatchSize::CountElements,
+ [](auto& Copy) { std::make_heap(Copy.begin(), Copy.end()); });
+ }
+
+ std::string name() const {
+ return "BM_MakeHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark<MakeHeap, AllValueTypes, AllOrders>(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/libcxx/benchmarks/algorithms/make_heap_then_sort_heap.bench.cpp b/libcxx/benchmarks/algorithms/make_heap_then_sort_heap.bench.cpp
new file mode 100644
index 000000000000..5254c261e3ec
--- /dev/null
+++ b/libcxx/benchmarks/algorithms/make_heap_then_sort_heap.bench.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+
+#include "common.h"
+
+namespace {
+template <class ValueType, class Order>
+struct MakeThenSortHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(state, Quantity, Order(), BatchSize::CountElements,
+ [](auto& Copy) {
+ std::make_heap(Copy.begin(), Copy.end());
+ std::sort_heap(Copy.begin(), Copy.end());
+ });
+ }
+
+ std::string name() const {
+ return "BM_MakeThenSortHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark<MakeThenSortHeap, AllValueTypes, AllOrders>(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/libcxx/benchmarks/algorithms/min_max_element.bench.cpp b/libcxx/benchmarks/algorithms/min_max_element.bench.cpp
new file mode 100644
index 000000000000..e2c642365610
--- /dev/null
+++ b/libcxx/benchmarks/algorithms/min_max_element.bench.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+
+#include "common.h"
+
+namespace {
+template <class ValueType, class Order>
+struct MinMaxElement {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
+ benchmark::DoNotOptimize(std::minmax_element(Copy.begin(), Copy.end()));
+ });
+ }
+
+ std::string name() const {
+ return "BM_MinMaxElement" + ValueType::name() + Order::name() + "_" + std::to_string(Quantity);
+ }
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark<MinMaxElement, AllValueTypes, AllOrders>(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/libcxx/benchmarks/algorithms/pop_heap.bench.cpp b/libcxx/benchmarks/algorithms/pop_heap.bench.cpp
new file mode 100644
index 000000000000..ef6e5a669740
--- /dev/null
+++ b/libcxx/benchmarks/algorithms/pop_heap.bench.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+
+#include "common.h"
+
+namespace {
+template <class ValueType>
+struct PopHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(
+ state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
+ for (auto B = Copy.begin(), I = Copy.end(); I != B; --I) {
+ std::pop_heap(B, I);
+ }
+ });
+ }
+
+ std::string name() const {
+ return "BM_PopHeap" + ValueType::name() + "_" + std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark<PopHeap, AllValueTypes>(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/libcxx/benchmarks/algorithms/push_heap.bench.cpp b/libcxx/benchmarks/algorithms/push_heap.bench.cpp
new file mode 100644
index 000000000000..8c333240f7ca
--- /dev/null
+++ b/libcxx/benchmarks/algorithms/push_heap.bench.cpp
@@ -0,0 +1,42 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+
+#include "common.h"
+
+namespace {
+template <class ValueType, class Order>
+struct PushHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(
+ state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
+ for (auto I = Copy.begin(), E = Copy.end(); I != E; ++I) {
+ std::push_heap(Copy.begin(), I + 1);
+ }
+ });
+ }
+
+ bool skip() const { return Order() == ::Order::Heap; }
+
+ std::string name() const {
+ return "BM_PushHeap" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark<PushHeap, AllValueTypes, AllOrders>(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/libcxx/benchmarks/algorithms/sort.bench.cpp b/libcxx/benchmarks/algorithms/sort.bench.cpp
new file mode 100644
index 000000000000..6f8b12efe453
--- /dev/null
+++ b/libcxx/benchmarks/algorithms/sort.bench.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+
+#include "common.h"
+
+namespace {
+template <class ValueType, class Order>
+struct Sort {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(
+ state, Quantity, Order(), BatchSize::CountElements,
+ [](auto& Copy) { std::sort(Copy.begin(), Copy.end()); });
+ }
+
+ bool skip() const { return Order() == ::Order::Heap; }
+
+ std::string name() const {
+ return "BM_Sort" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark<Sort, AllValueTypes, AllOrders>(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/libcxx/benchmarks/algorithms/sort_heap.bench.cpp b/libcxx/benchmarks/algorithms/sort_heap.bench.cpp
new file mode 100644
index 000000000000..a217211a2f8e
--- /dev/null
+++ b/libcxx/benchmarks/algorithms/sort_heap.bench.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+
+#include "common.h"
+
+namespace {
+template <class ValueType>
+struct SortHeap {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(
+ state, Quantity, Order::Heap, BatchSize::CountElements,
+ [](auto& Copy) { std::sort_heap(Copy.begin(), Copy.end()); });
+ }
+
+ std::string name() const {
+ return "BM_SortHeap" + ValueType::name() + "_" + std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark<SortHeap, AllValueTypes>(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}
diff --git a/libcxx/benchmarks/algorithms/stable_sort.bench.cpp b/libcxx/benchmarks/algorithms/stable_sort.bench.cpp
new file mode 100644
index 000000000000..1ef55ce9fe95
--- /dev/null
+++ b/libcxx/benchmarks/algorithms/stable_sort.bench.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <algorithm>
+
+#include "common.h"
+
+namespace {
+template <class ValueType, class Order>
+struct StableSort {
+ size_t Quantity;
+
+ void run(benchmark::State& state) const {
+ runOpOnCopies<ValueType>(
+ state, Quantity, Order(), BatchSize::CountElements,
+ [](auto& Copy) { std::stable_sort(Copy.begin(), Copy.end()); });
+ }
+
+ bool skip() const { return Order() == ::Order::Heap; }
+
+ std::string name() const {
+ return "BM_StableSort" + ValueType::name() + Order::name() + "_" +
+ std::to_string(Quantity);
+ };
+};
+} // namespace
+
+int main(int argc, char** argv) {
+ benchmark::Initialize(&argc, argv);
+ if (benchmark::ReportUnrecognizedArguments(argc, argv))
+ return 1;
+ makeCartesianProductBenchmark<StableSort, AllValueTypes, AllOrders>(Quantities);
+ benchmark::RunSpecifiedBenchmarks();
+}