[libcxx-commits] [libcxx] [libc++] Make __synth_three_way cheaper to build in common case (PR #227580)
Nico Weber via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Oct 22 07:52:52 PDT 2026
nico wrote:
Sorry for the slow reply here. I had written a draft reply but wasn't fully done, then my laptop rebooted and I lost it. This time, I'll write the first part and send it first, and then hopefully the second part soon after 😅
First, it'd obviously be great if we could make three_way_comparable_with itself better. But I think your proposal doesn't work, both in practice, and in theory.
First, in practice. Here's a demo program:
```
% cat synth_three_way_bench.cc
#include <compare>
#include <optional>
#include <tuple>
#include <utility>
#include <vector>
#ifndef N
#define N 100
#endif
template <int I>
struct S {
int x;
auto operator<=>(const S&) const = default;
};
template <int I>
bool compare_one() {
bool r = false;
r |= std::optional<S<I + 0 * N>>{} < std::optional<S<I + 0 * N>>{};
r |= std::pair<S<I + 1 * N>, int>{} < std::pair<S<I + 1 * N>, int>{};
r |= std::tuple<S<I + 2 * N>>{} < std::tuple<S<I + 2 * N>>{};
r |= std::vector<S<I + 3 * N>>{} < std::vector<S<I + 3 * N>>{};
return r;
}
template <int... Is>
bool compare_several(std::integer_sequence<int, Is...>) {
bool r = false;
bool results[] = {(r |= compare_one<Is>())...};
(void)results;
return r;
}
bool foo() { return compare_several(std::make_integer_sequence<int, N>{}); }
```
It's a bit synthetic, but remember that this PR here speeds up actual real-life builds, so it's somewhat representative.
Timing `bin/clang -fsyntax-only synth_three_way_bench.cc -std=c++23 -isysroot $(xcrun -show-sdk-path)`, this patch here is a 23% speedup compared to HEAD, while your version is a 12% speedup on my machine. So it's only about half as helpful in practice.
This PR used to be a 35% speedup on that example before #227584.
Now, you might say "well, if that PR was so good, maybe we should just optimize concepts in clang instead!". And yes, we should do that. I have a local branch that does this quite a bit (https://github.com/llvm/llvm-project/issues/229808). On that branch, this PR is still a 12.4% compile time win on that example above, while your proposal is only a 2% win.
Second, I think the standard does effectively not allow changing three_way_comparable_with. That's the second part that I'll hopefully write up soon.
I agree these three lines are pretty ad-hoc. But they're also limited to a single file, and the win is hopefully big enough to justify them :)
https://github.com/llvm/llvm-project/pull/227580
More information about the libcxx-commits
mailing list