Skip to content

Commit 47823b9

Browse files
committed
[libc++] Add benchmark for std::exception_ptr
This commit adds benchmarks for `std::exception_ptr` to set a baseline in preparation for follow-up optimizations.
1 parent a80a6b3 commit 47823b9

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

libcxx/test/benchmarks/exception_ptr.bench.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,49 @@ void bm_make_exception_ptr(benchmark::State& state) {
1818
}
1919
BENCHMARK(bm_make_exception_ptr)->ThreadRange(1, 8);
2020

21+
static bool exception_ptr_moves_copies_swap(std::exception_ptr p1) {
22+
// Taken from https://github.com/llvm/llvm-project/issues/44892
23+
std::exception_ptr p2(p1); // Copy constructor
24+
std::exception_ptr p3(std::move(p2)); // Move constructor
25+
p2 = std::move(p1); // Move assignment
26+
p1 = p2; // Copy assignment
27+
swap(p1, p2); // Swap
28+
// Comparisons against nullptr. The overhead from creating temporary `exception_ptr`
29+
// instances should be optimized out.
30+
bool is_null = p1 == nullptr && nullptr == p2;
31+
bool is_equal = p1 == p2; // Comparison
32+
return is_null && is_equal;
33+
}
34+
35+
void bm_nonnull_exception_ptr(benchmark::State& state) {
36+
std::exception_ptr excptr = std::make_exception_ptr(42);
37+
for (auto _ : state) {
38+
benchmark::DoNotOptimize(excptr);
39+
benchmark::DoNotOptimize(exception_ptr_moves_copies_swap(excptr));
40+
}
41+
}
42+
BENCHMARK(bm_nonnull_exception_ptr);
43+
44+
void bm_null_exception_ptr(benchmark::State& state) {
45+
std::exception_ptr excptr;
46+
for (auto _ : state) {
47+
// All of the `exception_ptr_noops` are no-ops but the optimizer
48+
// cannot optimize them away, because the `DoNotOptimize` calls
49+
// prevent the optimizer from doing so.
50+
benchmark::DoNotOptimize(excptr);
51+
benchmark::DoNotOptimize(exception_ptr_moves_copies_swap(excptr));
52+
}
53+
}
54+
BENCHMARK(bm_null_exception_ptr);
55+
56+
void bm_optimized_null_exception_ptr(benchmark::State& state) {
57+
for (auto _ : state) {
58+
// All of the `exception_ptr_noops` are no-ops because
59+
// the exception_ptr is empty. Hence, the compiler should
60+
// be able to optimize them very aggressively.
61+
benchmark::DoNotOptimize(exception_ptr_moves_copies_swap(std::exception_ptr{nullptr}));
62+
}
63+
}
64+
BENCHMARK(bm_optimized_null_exception_ptr);
65+
2166
BENCHMARK_MAIN();

0 commit comments

Comments
 (0)