Skip to content

Commit f94a447

Browse files
committed
[libc++] Granularize algorithm benchmarks
Reviewed By: ldionne, #libc Spies: libcxx-commits, mgorny, mgrang Differential Revision: https://reviews.llvm.org/D124740
1 parent b2f9bde commit f94a447

10 files changed

+365
-179
lines changed

libcxx/benchmarks/CMakeLists.txt

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,41 @@ endfunction()
159159
#==============================================================================
160160
# Register Benchmark tests
161161
#==============================================================================
162-
file(GLOB BENCHMARK_TESTS "*.bench.cpp")
162+
set(BENCHMARK_TESTS
163+
algorithms/make_heap_then_sort_heap.bench.cpp
164+
algorithms/make_heap.bench.cpp
165+
algorithms/min_max_element.bench.cpp
166+
algorithms/pop_heap.bench.cpp
167+
algorithms/push_heap.bench.cpp
168+
algorithms/sort_heap.bench.cpp
169+
algorithms/stable_sort.bench.cpp
170+
algorithms.partition_point.bench.cpp
171+
allocation.bench.cpp
172+
deque.bench.cpp
173+
filesystem.bench.cpp
174+
function.bench.cpp
175+
map.bench.cpp
176+
ordered_set.bench.cpp
177+
string.bench.cpp
178+
stringstream.bench.cpp
179+
to_chars.bench.cpp
180+
unordered_set_operations.bench.cpp
181+
util_smartptr.bench.cpp
182+
variant_visit_1.bench.cpp
183+
variant_visit_2.bench.cpp
184+
variant_visit_3.bench.cpp
185+
vector_operations.bench.cpp
186+
)
163187

164-
if (NOT LIBCXX_ENABLE_INCOMPLETE_FEATURES)
165-
list(FILTER BENCHMARK_TESTS EXCLUDE REGEX "(format_to_n|format_to|format|formatted_size|formatter_float|std_format_spec_string_unicode).bench.cpp")
188+
if (LIBCXX_ENABLE_INCOMPLETE_FEATURES)
189+
set(BENCHMARK_TESTS
190+
${BENCHMARK_TESTS}
191+
format_to_n.bench.cpp
192+
format_to.bench.cpp
193+
format.bench.cpp
194+
formatted_size.bench.cpp
195+
formatter_float.bench.cpp
196+
std_format_spec_string_unicode.bench.cpp)
166197
endif()
167198

168199
foreach(test_path ${BENCHMARK_TESTS})
@@ -173,7 +204,7 @@ foreach(test_path ${BENCHMARK_TESTS})
173204
# Only report the adding of the benchmark once.
174205
set(${test_name}_REPORTED ON CACHE INTERNAL "")
175206
endif()
176-
add_benchmark_test(${test_name} ${test_file})
207+
add_benchmark_test(${test_name} ${test_path})
177208
endforeach()
178209

179210
if (LIBCXX_INCLUDE_TESTS)

libcxx/benchmarks/algorithms.bench.cpp renamed to libcxx/benchmarks/algorithms/common.h

Lines changed: 23 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
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+
#ifndef LIBCXX_ALGORITHMS_COMMON_H
10+
#define LIBCXX_ALGORITHMS_COMMON_H
111

212
#include <algorithm>
3-
#include <cstdint>
4-
#include <map>
5-
#include <random>
6-
#include <string>
7-
#include <utility>
13+
#include <numeric>
14+
#include <tuple>
815
#include <vector>
916

10-
#include "CartesianBenchmarks.h"
11-
#include "GenerateInput.h"
12-
#include "benchmark/benchmark.h"
13-
#include "test_macros.h"
14-
15-
namespace {
17+
#include "../CartesianBenchmarks.h"
18+
#include "../GenerateInput.h"
1619

1720
enum class ValueType { Uint32, Uint64, Pair, Tuple, String, Float };
1821
struct AllValueTypes : EnumValuesAsTuple<AllValueTypes, ValueType, 6> {
@@ -54,9 +57,9 @@ void fillAdversarialQuickSortInput(T& V, size_t N) {
5457
assert(N > 0);
5558
// If an element is equal to gas, it indicates that the value of the element
5659
// is still to be decided and may change over the course of time.
57-
const int gas = N - 1;
60+
const unsigned int gas = N - 1;
5861
V.resize(N);
59-
for (int i = 0; i < N; ++i) {
62+
for (unsigned int i = 0; i < N; ++i) {
6063
V[i] = gas;
6164
}
6265
// Candidate for the pivot position.
@@ -134,7 +137,7 @@ void fillValues(std::vector<std::tuple<T1, T2, T3> >& V, size_t N, Order O) {
134137
}
135138
}
136139

137-
void fillValues(std::vector<std::string>& V, size_t N, Order O) {
140+
inline void fillValues(std::vector<std::string>& V, size_t N, Order O) {
138141
if (O == Order::SingleElement) {
139142
V.resize(N, getRandomString(64));
140143
} else {
@@ -228,169 +231,14 @@ void runOpOnCopies(benchmark::State& state, size_t Quantity, Order O,
228231
}
229232
}
230233

231-
template <class ValueType, class Order>
232-
struct Sort {
233-
size_t Quantity;
234-
235-
void run(benchmark::State& state) const {
236-
runOpOnCopies<ValueType>(
237-
state, Quantity, Order(), BatchSize::CountElements,
238-
[](auto& Copy) { std::sort(Copy.begin(), Copy.end()); });
239-
}
240-
241-
bool skip() const { return Order() == ::Order::Heap; }
242-
243-
std::string name() const {
244-
return "BM_Sort" + ValueType::name() + Order::name() + "_" +
245-
std::to_string(Quantity);
246-
};
247-
};
248-
249-
template <class ValueType, class Order>
250-
struct StableSort {
251-
size_t Quantity;
252-
253-
void run(benchmark::State& state) const {
254-
runOpOnCopies<ValueType>(
255-
state, Quantity, Order(), BatchSize::CountElements,
256-
[](auto& Copy) { std::stable_sort(Copy.begin(), Copy.end()); });
257-
}
258-
259-
bool skip() const { return Order() == ::Order::Heap; }
260-
261-
std::string name() const {
262-
return "BM_StableSort" + ValueType::name() + Order::name() + "_" +
263-
std::to_string(Quantity);
264-
};
265-
};
266-
267-
template <class ValueType, class Order>
268-
struct MakeHeap {
269-
size_t Quantity;
270-
271-
void run(benchmark::State& state) const {
272-
runOpOnCopies<ValueType>(
273-
state, Quantity, Order(), BatchSize::CountElements,
274-
[](auto& Copy) { std::make_heap(Copy.begin(), Copy.end()); });
275-
}
276-
277-
std::string name() const {
278-
return "BM_MakeHeap" + ValueType::name() + Order::name() + "_" +
279-
std::to_string(Quantity);
280-
};
281-
};
282-
283-
template <class ValueType>
284-
struct SortHeap {
285-
size_t Quantity;
286-
287-
void run(benchmark::State& state) const {
288-
runOpOnCopies<ValueType>(
289-
state, Quantity, Order::Heap, BatchSize::CountElements,
290-
[](auto& Copy) { std::sort_heap(Copy.begin(), Copy.end()); });
291-
}
292-
293-
std::string name() const {
294-
return "BM_SortHeap" + ValueType::name() + "_" + std::to_string(Quantity);
295-
};
296-
};
297-
298-
template <class ValueType, class Order>
299-
struct MakeThenSortHeap {
300-
size_t Quantity;
301-
302-
void run(benchmark::State& state) const {
303-
runOpOnCopies<ValueType>(state, Quantity, Order(), BatchSize::CountElements,
304-
[](auto& Copy) {
305-
std::make_heap(Copy.begin(), Copy.end());
306-
std::sort_heap(Copy.begin(), Copy.end());
307-
});
308-
}
309-
310-
std::string name() const {
311-
return "BM_MakeThenSortHeap" + ValueType::name() + Order::name() + "_" +
312-
std::to_string(Quantity);
313-
};
314-
};
315-
316-
template <class ValueType, class Order>
317-
struct PushHeap {
318-
size_t Quantity;
319-
320-
void run(benchmark::State& state) const {
321-
runOpOnCopies<ValueType>(
322-
state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
323-
for (auto I = Copy.begin(), E = Copy.end(); I != E; ++I) {
324-
std::push_heap(Copy.begin(), I + 1);
325-
}
326-
});
327-
}
328-
329-
bool skip() const { return Order() == ::Order::Heap; }
330-
331-
std::string name() const {
332-
return "BM_PushHeap" + ValueType::name() + Order::name() + "_" +
333-
std::to_string(Quantity);
334-
};
335-
};
336-
337-
template <class ValueType>
338-
struct PopHeap {
339-
size_t Quantity;
340-
341-
void run(benchmark::State& state) const {
342-
runOpOnCopies<ValueType>(
343-
state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
344-
for (auto B = Copy.begin(), I = Copy.end(); I != B; --I) {
345-
std::pop_heap(B, I);
346-
}
347-
});
348-
}
349234

350-
std::string name() const {
351-
return "BM_PopHeap" + ValueType::name() + "_" + std::to_string(Quantity);
352-
};
353-
};
354-
355-
template <class ValueType, class Order>
356-
struct MinMaxElement {
357-
size_t Quantity;
358-
359-
void run(benchmark::State& state) const {
360-
runOpOnCopies<ValueType>(state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
361-
benchmark::DoNotOptimize(std::minmax_element(Copy.begin(), Copy.end()));
362-
});
363-
}
364-
365-
std::string name() const {
366-
return "BM_MinMaxElement" + ValueType::name() + Order::name() + "_" + std::to_string(Quantity);
367-
}
368-
};
369-
370-
} // namespace
371-
372-
int main(int argc, char** argv) {
373-
benchmark::Initialize(&argc, argv);
374-
if (benchmark::ReportUnrecognizedArguments(argc, argv))
375-
return 1;
376-
377-
const std::vector<size_t> Quantities = {1 << 0, 1 << 2, 1 << 4, 1 << 6,
378-
1 << 8, 1 << 10, 1 << 14,
235+
const std::vector<size_t> Quantities = {1 << 0, 1 << 2, 1 << 4, 1 << 6,
236+
1 << 8, 1 << 10, 1 << 14,
379237
// Running each benchmark in parallel consumes too much memory with MSAN
380238
// and can lead to the test process being killed.
381239
#if !TEST_HAS_FEATURE(memory_sanitizer)
382-
1 << 18
240+
1 << 18
383241
#endif
384-
};
385-
makeCartesianProductBenchmark<Sort, AllValueTypes, AllOrders>(Quantities);
386-
makeCartesianProductBenchmark<StableSort, AllValueTypes, AllOrders>(
387-
Quantities);
388-
makeCartesianProductBenchmark<MakeHeap, AllValueTypes, AllOrders>(Quantities);
389-
makeCartesianProductBenchmark<SortHeap, AllValueTypes>(Quantities);
390-
makeCartesianProductBenchmark<MakeThenSortHeap, AllValueTypes, AllOrders>(
391-
Quantities);
392-
makeCartesianProductBenchmark<PushHeap, AllValueTypes, AllOrders>(Quantities);
393-
makeCartesianProductBenchmark<PopHeap, AllValueTypes>(Quantities);
394-
makeCartesianProductBenchmark<MinMaxElement, AllValueTypes, AllOrders>(Quantities);
395-
benchmark::RunSpecifiedBenchmarks();
396-
}
242+
};
243+
244+
#endif // LIBCXX_ALGORITHMS_COMMON_H
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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+
#include <algorithm>
10+
11+
#include "common.h"
12+
13+
namespace {
14+
template <class ValueType, class Order>
15+
struct MakeHeap {
16+
size_t Quantity;
17+
18+
void run(benchmark::State& state) const {
19+
runOpOnCopies<ValueType>(
20+
state, Quantity, Order(), BatchSize::CountElements,
21+
[](auto& Copy) { std::make_heap(Copy.begin(), Copy.end()); });
22+
}
23+
24+
std::string name() const {
25+
return "BM_MakeHeap" + ValueType::name() + Order::name() + "_" +
26+
std::to_string(Quantity);
27+
};
28+
};
29+
} // namespace
30+
31+
int main(int argc, char** argv) {
32+
benchmark::Initialize(&argc, argv);
33+
if (benchmark::ReportUnrecognizedArguments(argc, argv))
34+
return 1;
35+
makeCartesianProductBenchmark<MakeHeap, AllValueTypes, AllOrders>(Quantities);
36+
benchmark::RunSpecifiedBenchmarks();
37+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
#include <algorithm>
10+
11+
#include "common.h"
12+
13+
namespace {
14+
template <class ValueType, class Order>
15+
struct MakeThenSortHeap {
16+
size_t Quantity;
17+
18+
void run(benchmark::State& state) const {
19+
runOpOnCopies<ValueType>(state, Quantity, Order(), BatchSize::CountElements,
20+
[](auto& Copy) {
21+
std::make_heap(Copy.begin(), Copy.end());
22+
std::sort_heap(Copy.begin(), Copy.end());
23+
});
24+
}
25+
26+
std::string name() const {
27+
return "BM_MakeThenSortHeap" + ValueType::name() + Order::name() + "_" +
28+
std::to_string(Quantity);
29+
};
30+
};
31+
} // namespace
32+
33+
int main(int argc, char** argv) {
34+
benchmark::Initialize(&argc, argv);
35+
if (benchmark::ReportUnrecognizedArguments(argc, argv))
36+
return 1;
37+
makeCartesianProductBenchmark<MakeThenSortHeap, AllValueTypes, AllOrders>(Quantities);
38+
benchmark::RunSpecifiedBenchmarks();
39+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
#include <algorithm>
10+
11+
#include "common.h"
12+
13+
namespace {
14+
template <class ValueType, class Order>
15+
struct MinMaxElement {
16+
size_t Quantity;
17+
18+
void run(benchmark::State& state) const {
19+
runOpOnCopies<ValueType>(state, Quantity, Order(), BatchSize::CountElements, [](auto& Copy) {
20+
benchmark::DoNotOptimize(std::minmax_element(Copy.begin(), Copy.end()));
21+
});
22+
}
23+
24+
std::string name() const {
25+
return "BM_MinMaxElement" + ValueType::name() + Order::name() + "_" + std::to_string(Quantity);
26+
}
27+
};
28+
} // namespace
29+
30+
int main(int argc, char** argv) {
31+
benchmark::Initialize(&argc, argv);
32+
if (benchmark::ReportUnrecognizedArguments(argc, argv))
33+
return 1;
34+
makeCartesianProductBenchmark<MinMaxElement, AllValueTypes, AllOrders>(Quantities);
35+
benchmark::RunSpecifiedBenchmarks();
36+
}

0 commit comments

Comments
 (0)