[libcxx-commits] [libcxx] [libc++] Optimize std::swap of locales (PR #209760)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jul 15 05:56:10 PDT 2026


https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/209760

Currently we copy construct `locale`s whenever we swap, which is quite expensive for locales. We can just swap the pointers instead.


>From 521b03ada932c20ad63345557805af1c20d0ff47 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Wed, 15 Jul 2026 14:55:14 +0200
Subject: [PATCH] [libc++] Optimize std::swap of locales

---
 libcxx/include/__locale                       |  6 ++++
 .../localization}/ctype.bench.cpp             |  0
 .../text/localization/locale.bench.cpp        | 28 +++++++++++++++++++
 .../localization}/num_get.bench.cpp           |  0
 .../localization}/num_put.bench.cpp           |  0
 5 files changed, 34 insertions(+)
 rename libcxx/test/benchmarks/{locale => text/localization}/ctype.bench.cpp (100%)
 create mode 100644 libcxx/test/benchmarks/text/localization/locale.bench.cpp
 rename libcxx/test/benchmarks/{locale => text/localization}/num_get.bench.cpp (100%)
 rename libcxx/test/benchmarks/{locale => text/localization}/num_put.bench.cpp (100%)

diff --git a/libcxx/include/__locale b/libcxx/include/__locale
index bb8f8e7bbf5d9..8f29d713909cc 100644
--- a/libcxx/include/__locale
+++ b/libcxx/include/__locale
@@ -143,8 +143,14 @@ private:
   friend bool has_facet(const locale&) _NOEXCEPT;
   template <class _Facet>
   friend const _Facet& use_facet(const locale&);
+
+  friend void swap(locale&, locale&);
 };
 
+inline void swap(locale& __lhs, locale& __rhs) {
+  std::swap(__lhs.__locale_, __rhs.__locale_);
+}
+
 class _LIBCPP_EXPORTED_FROM_ABI locale::facet : public __shared_count {
 protected:
   _LIBCPP_HIDE_FROM_ABI explicit facet(size_t __refs = 0) : __shared_count(static_cast<long>(__refs) - 1) {}
diff --git a/libcxx/test/benchmarks/locale/ctype.bench.cpp b/libcxx/test/benchmarks/text/localization/ctype.bench.cpp
similarity index 100%
rename from libcxx/test/benchmarks/locale/ctype.bench.cpp
rename to libcxx/test/benchmarks/text/localization/ctype.bench.cpp
diff --git a/libcxx/test/benchmarks/text/localization/locale.bench.cpp b/libcxx/test/benchmarks/text/localization/locale.bench.cpp
new file mode 100644
index 0000000000000..60bc541bc053f
--- /dev/null
+++ b/libcxx/test/benchmarks/text/localization/locale.bench.cpp
@@ -0,0 +1,28 @@
+
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+#include <ios>
+#include <locale>
+
+#include <benchmark/benchmark.h>
+
+static void BM_num_get(benchmark::State& state) {
+  std::locale loc1, loc2;
+
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(loc1);
+    benchmark::DoNotOptimize(loc2);
+    std::swap(loc1, loc2);
+  }
+}
+BENCHMARK(BM_num_get)->Name("std::swap(std::locale&, std::locale&)");
+
+BENCHMARK_MAIN();
diff --git a/libcxx/test/benchmarks/locale/num_get.bench.cpp b/libcxx/test/benchmarks/text/localization/num_get.bench.cpp
similarity index 100%
rename from libcxx/test/benchmarks/locale/num_get.bench.cpp
rename to libcxx/test/benchmarks/text/localization/num_get.bench.cpp
diff --git a/libcxx/test/benchmarks/locale/num_put.bench.cpp b/libcxx/test/benchmarks/text/localization/num_put.bench.cpp
similarity index 100%
rename from libcxx/test/benchmarks/locale/num_put.bench.cpp
rename to libcxx/test/benchmarks/text/localization/num_put.bench.cpp



More information about the libcxx-commits mailing list