[libcxx-commits] [libcxx] [libc++] Add benchmarks for std::next_permutation and std::prev_permutation (PR #210966)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jul 21 05:35:35 PDT 2026


https://github.com/ldionne created https://github.com/llvm/llvm-project/pull/210966

None

>From 151e7dba173ca307ea91d13b387dcaf90368b30a Mon Sep 17 00:00:00 2001
From: Louis Dionne <ldionne.2 at gmail.com>
Date: Wed, 1 Jul 2026 14:21:02 -0400
Subject: [PATCH] [libc++] Add benchmarks for std::next_permutation and
 std::prev_permutation

---
 .../algorithms/sorting/permutation.bench.cpp  | 76 +++++++++++++++++++
 1 file changed, 76 insertions(+)
 create mode 100644 libcxx/test/benchmarks/algorithms/sorting/permutation.bench.cpp

diff --git a/libcxx/test/benchmarks/algorithms/sorting/permutation.bench.cpp b/libcxx/test/benchmarks/algorithms/sorting/permutation.bench.cpp
new file mode 100644
index 0000000000000..8834c595361fa
--- /dev/null
+++ b/libcxx/test/benchmarks/algorithms/sorting/permutation.bench.cpp
@@ -0,0 +1,76 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+
+#include <algorithm>
+#include <cstddef>
+#include <deque>
+#include <list>
+#include <string>
+#include <vector>
+
+#include "benchmark/benchmark.h"
+#include "common.h"
+
+int main(int argc, char** argv) {
+  auto std_next_permutation = [](auto first, auto last) { return std::next_permutation(first, last); };
+  auto std_prev_permutation = [](auto first, auto last) { return std::prev_permutation(first, last); };
+
+  // Benchmark next_permutation and prev_permutation. We walk the permutation sequence in place,
+  // calling the algorithm repeatedly without restoring between calls: these algorithms cycle through
+  // all permutations, so this measures the realistic amortized per-step cost.
+  //
+  // We intentionally don't benchmark the predicated overloads because that makes the benchmark
+  // run too slowly.
+  {
+    auto bm = []<class Container>(std::string name, auto permutation, auto generate_data) {
+      benchmark::RegisterBenchmark(
+          name,
+          [permutation, generate_data](auto& st) {
+            std::size_t const size      = st.range(0);
+            using ValueType             = typename Container::value_type;
+            std::vector<ValueType> data = generate_data(size);
+            Container c(data.begin(), data.end());
+
+            for (auto _ : st) {
+              benchmark::DoNotOptimize(c);
+              auto result = permutation(c.begin(), c.end());
+              benchmark::DoNotOptimize(result);
+              benchmark::DoNotOptimize(c);
+            }
+          })
+          ->Arg(8)
+          ->Arg(1024)
+          ->Arg(8192);
+    };
+
+    auto gen_int         = [](std::size_t size) { return support::shuffled_data<int>(size); };
+    auto gen_nonintegral = [](std::size_t size) {
+      std::vector<int> data = support::shuffled_data<int>(size);
+      return std::vector<support::NonIntegral>(data.begin(), data.end());
+    };
+
+    // clang-format off
+    bm.operator()<std::vector<int>>("std::next_permutation(vector<int>)", std_next_permutation, gen_int);
+    bm.operator()<std::vector<support::NonIntegral>>("std::next_permutation(vector<NonIntegral>)", std_next_permutation, gen_nonintegral);
+    bm.operator()<std::deque<int>>("std::next_permutation(deque<int>)", std_next_permutation, gen_int);
+    bm.operator()<std::list<int>>("std::next_permutation(list<int>)", std_next_permutation, gen_int);
+
+    bm.operator()<std::vector<int>>("std::prev_permutation(vector<int>)", std_prev_permutation, gen_int);
+    bm.operator()<std::vector<support::NonIntegral>>("std::prev_permutation(vector<NonIntegral>)", std_prev_permutation, gen_nonintegral);
+    bm.operator()<std::deque<int>>("std::prev_permutation(deque<int>)", std_prev_permutation, gen_int);
+    bm.operator()<std::list<int>>("std::prev_permutation(list<int>)", std_prev_permutation, gen_int);
+    // clang-format on
+  }
+
+  benchmark::Initialize(&argc, argv);
+  benchmark::RunSpecifiedBenchmarks();
+  benchmark::Shutdown();
+  return 0;
+}



More information about the libcxx-commits mailing list