[libcxx-commits] [libcxx] [libc++] Optimize ranges::move{, _backward} for vector<bool>::iterator (PR #121109)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Feb 5 09:04:43 PST 2025


================
@@ -0,0 +1,55 @@
+//===----------------------------------------------------------------------===//
+//
+// 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, c++11, c++14, c++17, c++20
+
+#include <algorithm>
+#include <benchmark/benchmark.h>
+#include <vector>
+
+static void bm_ranges_move_vb(benchmark::State& state, bool aligned) {
+  auto n = state.range();
+  std::vector<bool> in(n, true);
+  std::vector<bool> out(aligned ? n : n + 8);
+  benchmark::DoNotOptimize(&in);
+  auto dst = aligned ? out.begin() : out.begin() + 4;
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(std::ranges::move(in, dst));
+    benchmark::DoNotOptimize(&out);
+  }
+}
----------------
ldionne wrote:

To avoid moving from an already moved-from range, I would suggest the following instead:

```c++
auto n = state.range();
std::vector<bool> v1(n, true);
std::vector<bool> v2(n, false);
benchmark::DoNotOptimize(v1);
benchmark::DoNotOptimize(v2);
std::vector<bool>* in = &v1;
std::vector<bool>* out = &v2;

for (auto _ : state) {
  benchmark::DoNotOptimize(std::ranges::move(*in, out->begin()));
  benchmark::DoNotOptimize(out);
  in = (in == &v1 ? &v2 : &v1);
  out = (out == &v1 ? &v2 : &v1);
}
```

I am not certain how to deal with the un-aligned case though. If this turns out to be too hard to solve, maybe we can just leave it as-is.

https://github.com/llvm/llvm-project/pull/121109


More information about the libcxx-commits mailing list