diff --git a/libcxx/benchmarks/algorithms.bench.cpp b/libcxx/benchmarks/algorithms.bench.cpp --- a/libcxx/benchmarks/algorithms.bench.cpp +++ b/libcxx/benchmarks/algorithms.bench.cpp @@ -14,14 +14,19 @@ namespace { -enum class ValueType { Uint32, Uint64, Pair, Tuple, String, Float }; -struct AllValueTypes : EnumValuesAsTuple { +enum class ValueType { Uint32, Uint64, Pair, Tuple, String, Float, ExpensiveToMove }; +struct AllValueTypes : EnumValuesAsTuple { static constexpr const char* Names[] = {"uint32", "uint64", "pair", "tuple", - "string", "float"}; + "string", "float", "ExpensiveToMove"}; +}; + +struct ExpensiveToMove { + int a[256]; + std::strong_ordering operator<=>(const ExpensiveToMove&) const = default; }; using Types = std::tuple< uint32_t, uint64_t, std::pair, std::tuple, - std::string, float >; + std::string, float, ExpensiveToMove >; template using Value = std::tuple_element_t<(int)V::value, Types>; @@ -143,6 +148,20 @@ } } +void fillValues(std::vector& V, size_t N, Order O) { + if (O == Order::SingleElement) { + V.resize(N, ExpensiveToMove{}); + } else { + while (V.size() != N) { + ExpensiveToMove e; + for (size_t i = 0; i != 256; ++i) { + e.a[i] = V.size() + i; + } + V.push_back(e); + } + } +} + template void sortValues(T& V, Order O) { switch (O) { @@ -367,6 +386,22 @@ } }; +template +struct Rotate { + size_t Quantity; + mutable std::mt19937_64 rng; + + void run(benchmark::State& state) const { + runOpOnCopies(state, Quantity, Order(), BatchSize::CountBatch, [&](auto& Copy) { + benchmark::DoNotOptimize(std::rotate(Copy.begin(), Copy.begin() + (rng() % Copy.size()), Copy.end())); + }); + } + + std::string name() const { + return "BM_Rotate" + ValueType::name() + Order::name() + "_" + std::to_string(Quantity); + } +}; + } // namespace int main(int argc, char** argv) { @@ -392,5 +427,6 @@ makeCartesianProductBenchmark(Quantities); makeCartesianProductBenchmark(Quantities); makeCartesianProductBenchmark(Quantities); + makeCartesianProductBenchmark(Quantities); benchmark::RunSpecifiedBenchmarks(); } diff --git a/libcxx/include/__algorithm/rotate.h b/libcxx/include/__algorithm/rotate.h --- a/libcxx/include/__algorithm/rotate.h +++ b/libcxx/include/__algorithm/rotate.h @@ -83,7 +83,6 @@ } return __r; } - template inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 _Integral @@ -172,7 +171,7 @@ random_access_iterator_tag) { typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - if (is_trivially_move_assignable::value) + if _LIBCPP_CONSTEXPR_AFTER_CXX14 (is_trivially_move_assignable::value && sizeof(value_type) > 32) { if (_VSTD::next(__first) == __middle) return _VSTD::__rotate_left(__first, __last);