llvm-capstone/libcxx/benchmarks/deque_iterator.bench.cpp
Nikolas Klauser c90801457f [libc++] Refactor deque::iterator algorithm optimizations
This has multiple benefits:
- The optimizations are also performed for the `ranges::` versions of the algorithms
- Code duplication is reduced
- it is simpler to add this optimization for other segmented iterators,
  like `ranges::join_view::iterator`
- Algorithm code is removed from `<deque>`

Reviewed By: ldionne, huixie90, #libc

Spies: mstorsjo, sstefan1, EricWF, libcxx-commits, mgorny

Differential Revision: https://reviews.llvm.org/D132505
2023-01-19 20:11:43 +01:00

233 lines
7.7 KiB
C++

//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include <algorithm>
#include <deque>
#include "benchmark/benchmark.h"
namespace {
void run_sizes(auto benchmark) {
benchmark->Arg(0)
->Arg(1)
->Arg(2)
->Arg(64)
->Arg(512)
->Arg(1024)
->Arg(4000)
->Arg(4096)
->Arg(5500)
->Arg(64000)
->Arg(65536)
->Arg(70000);
}
template <class FromContainer, class ToContainer, class Func>
void benchmark_containers(benchmark::State& state, FromContainer& d, ToContainer& v, Func&& func) {
for (auto _ : state) {
benchmark::DoNotOptimize(v);
benchmark::DoNotOptimize(d);
func(d.begin(), d.end(), v.begin());
}
}
template <class Func>
void benchmark_deque_vector(benchmark::State& state, Func&& func) {
auto size = state.range(0);
std::deque<int> d;
d.resize(size);
std::ranges::fill(d, 10);
std::vector<int> v;
v.resize(size);
benchmark_containers(state, d, v, func);
}
template <class Func>
void benchmark_deque_deque(benchmark::State& state, Func&& func) {
auto size = state.range(0);
std::deque<int> d;
d.resize(size);
std::ranges::fill(d, 10);
std::deque<int> v;
v.resize(size);
benchmark_containers(state, d, v, func);
}
template <class Func>
void benchmark_vector_deque(benchmark::State& state, Func&& func) {
auto size = state.range(0);
std::vector<int> d;
d.resize(size);
std::ranges::fill(d, 10);
std::deque<int> v;
v.resize(size);
benchmark_containers(state, d, v, func);
}
template <class FromContainer, class ToContainer, class Func>
void benchmark_containers_backward(benchmark::State& state, FromContainer& d, ToContainer& v, Func&& func) {
for (auto _ : state) {
benchmark::DoNotOptimize(v);
benchmark::DoNotOptimize(d);
func(d.begin(), d.end(), v.end());
}
}
template <class Func>
void benchmark_deque_vector_backward(benchmark::State& state, Func&& func) {
auto size = state.range(0);
std::deque<int> d;
d.resize(size);
std::ranges::fill(d, 10);
std::vector<int> v;
v.resize(size);
benchmark_containers_backward(state, d, v, func);
}
template <class Func>
void benchmark_deque_deque_backward(benchmark::State& state, Func&& func) {
auto size = state.range(0);
std::deque<int> d;
d.resize(size);
std::ranges::fill(d, 10);
std::deque<int> v;
v.resize(size);
benchmark_containers_backward(state, d, v, func);
}
template <class Func>
void benchmark_vector_deque_backward(benchmark::State& state, Func&& func) {
auto size = state.range(0);
std::vector<int> d;
d.resize(size);
std::ranges::fill(d, 10);
std::deque<int> v;
v.resize(size);
benchmark_containers_backward(state, d, v, func);
}
struct CopyFunctor {
template <class... Args>
auto operator()(Args... args) const {
std::copy(std::forward<Args>(args)...);
}
} copy;
struct MoveFunctor {
template <class... Args>
auto operator()(Args... args) const {
std::move(std::forward<Args>(args)...);
}
} move;
struct CopyBackwardFunctor {
template <class... Args>
auto operator()(Args... args) const {
std::copy_backward(std::forward<Args>(args)...);
}
} copy_backward;
struct MoveBackwardFunctor {
template <class... Args>
auto operator()(Args... args) const {
std::move_backward(std::forward<Args>(args)...);
}
} move_backward;
// copy
void BM_deque_vector_copy(benchmark::State& state) { benchmark_deque_vector(state, copy); }
BENCHMARK(BM_deque_vector_copy)->Apply(run_sizes);
void BM_deque_vector_ranges_copy(benchmark::State& state) { benchmark_deque_vector(state, std::ranges::copy); }
BENCHMARK(BM_deque_vector_ranges_copy)->Apply(run_sizes);
void BM_deque_deque_copy(benchmark::State& state) { benchmark_deque_deque(state, copy); }
BENCHMARK(BM_deque_deque_copy)->Apply(run_sizes);
void BM_deque_deque_ranges_copy(benchmark::State& state) { benchmark_deque_deque(state, std::ranges::copy); }
BENCHMARK(BM_deque_deque_ranges_copy)->Apply(run_sizes);
void BM_vector_deque_copy(benchmark::State& state) { benchmark_vector_deque(state, copy); }
BENCHMARK(BM_vector_deque_copy)->Apply(run_sizes);
void BM_vector_deque_ranges_copy(benchmark::State& state) { benchmark_vector_deque(state, std::ranges::copy); }
BENCHMARK(BM_vector_deque_ranges_copy)->Apply(run_sizes);
// move
void BM_deque_vector_move(benchmark::State& state) { benchmark_deque_vector(state, move); }
BENCHMARK(BM_deque_vector_move)->Apply(run_sizes);
void BM_deque_vector_ranges_move(benchmark::State& state) { benchmark_deque_vector(state, std::ranges::move); }
BENCHMARK(BM_deque_vector_ranges_move)->Apply(run_sizes);
void BM_deque_deque_move(benchmark::State& state) { benchmark_deque_deque(state, move); }
BENCHMARK(BM_deque_deque_move)->Apply(run_sizes);
void BM_deque_deque_ranges_move(benchmark::State& state) { benchmark_deque_deque(state, std::ranges::move); }
BENCHMARK(BM_deque_deque_ranges_move)->Apply(run_sizes);
void BM_vector_deque_move(benchmark::State& state) { benchmark_vector_deque(state, move); }
BENCHMARK(BM_vector_deque_move)->Apply(run_sizes);
void BM_vector_deque_ranges_move(benchmark::State& state) { benchmark_vector_deque(state, std::ranges::move); }
BENCHMARK(BM_vector_deque_ranges_move)->Apply(run_sizes);
// copy_backward
void BM_deque_vector_copy_backward(benchmark::State& state) { benchmark_deque_vector_backward(state, copy_backward); }
BENCHMARK(BM_deque_vector_copy_backward)->Apply(run_sizes);
void BM_deque_vector_ranges_copy_backward(benchmark::State& state) {
benchmark_deque_vector_backward(state, std::ranges::copy_backward);
}
BENCHMARK(BM_deque_vector_ranges_copy_backward)->Apply(run_sizes);
void BM_deque_deque_copy_backward(benchmark::State& state) { benchmark_deque_deque_backward(state, copy_backward); }
BENCHMARK(BM_deque_deque_copy_backward)->Apply(run_sizes);
void BM_deque_deque_ranges_copy_backward(benchmark::State& state) {
benchmark_deque_deque_backward(state, std::ranges::copy_backward);
}
BENCHMARK(BM_deque_deque_ranges_copy_backward)->Apply(run_sizes);
void BM_vector_deque_copy_backward(benchmark::State& state) { benchmark_vector_deque_backward(state, copy_backward); }
BENCHMARK(BM_vector_deque_copy_backward)->Apply(run_sizes);
void BM_vector_deque_ranges_copy_backward(benchmark::State& state) {
benchmark_vector_deque_backward(state, std::ranges::copy_backward);
}
BENCHMARK(BM_vector_deque_ranges_copy_backward)->Apply(run_sizes);
// move_backward
void BM_deque_vector_move_backward(benchmark::State& state) { benchmark_deque_vector_backward(state, move_backward); }
BENCHMARK(BM_deque_vector_move_backward)->Apply(run_sizes);
void BM_deque_vector_ranges_move_backward(benchmark::State& state) {
benchmark_deque_vector_backward(state, std::ranges::move_backward);
}
BENCHMARK(BM_deque_vector_ranges_move_backward)->Apply(run_sizes);
void BM_deque_deque_move_backward(benchmark::State& state) { benchmark_deque_deque_backward(state, move_backward); }
BENCHMARK(BM_deque_deque_move_backward)->Apply(run_sizes);
void BM_deque_deque_ranges_move_backward(benchmark::State& state) {
benchmark_deque_deque_backward(state, std::ranges::move_backward);
}
BENCHMARK(BM_deque_deque_ranges_move_backward)->Apply(run_sizes);
void BM_vector_deque_move_backward(benchmark::State& state) { benchmark_vector_deque_backward(state, move_backward); }
BENCHMARK(BM_vector_deque_move_backward)->Apply(run_sizes);
void BM_vector_deque_ranges_move_backward(benchmark::State& state) {
benchmark_vector_deque_backward(state, std::ranges::move_backward);
}
BENCHMARK(BM_vector_deque_ranges_move_backward)->Apply(run_sizes);
} // namespace
BENCHMARK_MAIN();