[libcxx-commits] [libcxx] [libc++] Avoid double comparisons when uniquing flat_set/flat_map (PR #214118)
Adib Pathan via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Aug 4 21:01:29 PDT 2026
adxb-pxthxn wrote:
Pushed an update addressing the feedback, `__deduplicate_sorted` is now a regular member function that just uses `__compare_` directly — no predicate parameter, no unqualified calls, and no `static`-in-header ODR issues. The `__key_not_less` helper is gone too. I also moved the comparison-count tests out of the `std/` tests and into libc++-specific ones under `test/libcxx/`, now with `constexpr` coverage.
Since the previous PR got asked for benchmarks. I compiled the exact same program twice with the same compiler and flags (`-O2`), against header trees that differ *only* in `__flat_set/flat_set.h` and `__flat_map/flat_map.h` (main vs. this branch), linking the same `libc++.dylib`.
**Comparator call counts** (deterministic, so no measurement noise to argue about):
| Scenario | main | this PR |
|---|---|---|
| `flat_set` ctor, 10 equal keys (reproducer from #175035) | 27 | 18 |
| `flat_set` ctor, pre-sorted 1000 keys, 50% duplicates | 3505 | 3005 |
| `flat_map::insert(range)`, 1000 keys, 50% duplicates | 3505 | 3005 |
| `flat_set` ctor, unsorted 1000 unique keys | 12129 | 12129 (unchanged) |
So exactly one comparator call saved per duplicate pair, and the no-duplicate path is completely untouched.
**Wall-clock** (`std::string` keys with long common prefixes, N=8192, median of 15 trials, stable across runs): constructing from a pre-sorted range with duplicates — which isolates the dedup phase since the `is_sorted` check skips the sort — gets ~8–12% faster. Paths dominated by the initial sort see ~2–4%. With cheap comparators like `std::less<int>` the wall-clock win is smaller of course; it scales with how expensive the comparator is.
https://github.com/llvm/llvm-project/pull/214118
More information about the libcxx-commits
mailing list