From 699d71150a45f9fc4173f39dadc740465b854595 Mon Sep 17 00:00:00 2001 From: achabense <60953653+achabense@users.noreply.github.com> Date: Wed, 10 Sep 2025 21:19:14 +0800 Subject: [PATCH 1/4] benchmark --- benchmarks/CMakeLists.txt | 1 + benchmarks/src/any_swap.cpp | 42 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 benchmarks/src/any_swap.cpp diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index caab5625c60..eefc7869042 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -102,6 +102,7 @@ endfunction() add_benchmark(adjacent_difference src/adjacent_difference.cpp) add_benchmark(adjacent_find src/adjacent_find.cpp) +add_benchmark(any_swap src/any_swap.cpp) add_benchmark(bitset_from_string src/bitset_from_string.cpp) add_benchmark(bitset_to_string src/bitset_to_string.cpp) add_benchmark(efficient_nonlocking_print src/efficient_nonlocking_print.cpp) diff --git a/benchmarks/src/any_swap.cpp b/benchmarks/src/any_swap.cpp new file mode 100644 index 00000000000..4d2ec21744d --- /dev/null +++ b/benchmarks/src/any_swap.cpp @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include +#include +#include +#include + +using trivial = std::array; +static_assert(std::is_trivially_copyable_v); + +struct small { + std::array c{}; + small() = default; + small(const small&) = default; + small& operator=(const small&) = default; + small(small&&) noexcept = default; + small& operator=(small&&) noexcept = default; + ~small() {} +}; +static_assert(!std::is_trivially_copyable_v); +static_assert(std::is_nothrow_move_constructible_v); + +using large = std::array; + +template +void bm(benchmark::State& state) { + std::any a = T{}; + std::any b = T{}; + + for (auto _ : state) { + a.swap(b); + benchmark::DoNotOptimize(a); + benchmark::DoNotOptimize(b); + } +} + +BENCHMARK(bm); +BENCHMARK(bm); +BENCHMARK(bm); + +BENCHMARK_MAIN(); From 2944511990a373f97c46f052e750e32760ecf04d Mon Sep 17 00:00:00 2001 From: achabense <60953653+achabense@users.noreply.github.com> Date: Wed, 10 Sep 2025 21:20:36 +0800 Subject: [PATCH 2/4] Step 1 --- stl/inc/any | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stl/inc/any b/stl/inc/any index 2f33cb0545d..4a2f798d53d 100644 --- a/stl/inc/any +++ b/stl/inc/any @@ -230,7 +230,9 @@ public: } void swap(any& _That) noexcept { - _That = _STD exchange(*this, _STD move(_That)); + any _Old = _STD move(*this); + *this = _STD move(_That); + _That = _STD move(_Old); } // Observers [any.observers] From 5567c9c5703b4040f2c004a20ca26a40a549ff39 Mon Sep 17 00:00:00 2001 From: achabense <60953653+achabense@users.noreply.github.com> Date: Wed, 10 Sep 2025 21:22:00 +0800 Subject: [PATCH 3/4] Step 2 --- stl/inc/any | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stl/inc/any b/stl/inc/any index 4a2f798d53d..d0e2ea6a4ca 100644 --- a/stl/inc/any +++ b/stl/inc/any @@ -231,8 +231,9 @@ public: void swap(any& _That) noexcept { any _Old = _STD move(*this); - *this = _STD move(_That); - _That = _STD move(_Old); + _Assign(_STD move(_That)); + _That.reset(); + _That._Move_from(_Old); } // Observers [any.observers] From c1ca587440c7c63b4e20357704fb4c5464a08c4e Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Fri, 3 Oct 2025 09:23:52 -0700 Subject: [PATCH 4/4] Avoid another move construction. --- stl/inc/any | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stl/inc/any b/stl/inc/any index d0e2ea6a4ca..9aba1b3fb41 100644 --- a/stl/inc/any +++ b/stl/inc/any @@ -231,7 +231,8 @@ public: void swap(any& _That) noexcept { any _Old = _STD move(*this); - _Assign(_STD move(_That)); + reset(); + _Move_from(_That); _That.reset(); _That._Move_from(_Old); }