15 #include <benchmark/benchmark.h>
21 #include <range/v3/algorithm/transform.hpp>
22 #include <range/v3/iterator/insert_iterators.hpp>
23 #include <range/v3/range/access.hpp>
24 #include <range/v3/view/filter.hpp>
25 #include <range/v3/view/transform.hpp>
33 constexpr std::size_t kParticleCount = 1
'000'000;
41 using Particle = std::tuple<State, beluga::Weight, beluga::Cluster>;
48 std::vector<std::size_t> clusters;
50 [[nodiscard]] std::size_t size() const noexcept {
return states.size(); }
52 void clear() noexcept {
58 void reserve(std::size_t new_cap) {
61 clusters.reserve(new_cap);
64 void resize(std::size_t count) {
67 clusters.resize(count);
71 double update_weight(
const State&
state) {
75 void BM_Update_Baseline_StructureOfArrays(benchmark::State&
state) {
77 arrays.resize(kParticleCount);
78 for (
auto _ :
state) {
79 for (std::size_t i = 0; i < kParticleCount; ++i) {
80 arrays.weights[i] = update_weight(arrays.states[i]);
85 void BM_Update_Baseline_ArrayOfStructures(benchmark::State&
state) {
86 std::vector<Particle> particles;
87 particles.resize(kParticleCount);
88 for (
auto _ :
state) {
89 for (std::size_t i = 0; i < kParticleCount; ++i) {
90 auto&& particle = particles[i];
91 std::get<1>(particle) = update_weight(std::get<0>(particle));
96 template <
class Container>
97 void BM_Update(benchmark::State&
state) {
98 auto container = Container{};
99 container.resize(kParticleCount);
100 for (
auto _ :
state) {
106 BENCHMARK(BM_Update_Baseline_StructureOfArrays);
107 BENCHMARK_TEMPLATE(BM_Update, StructureOfArrays);
108 BENCHMARK(BM_Update_Baseline_ArrayOfStructures);
109 BENCHMARK_TEMPLATE(BM_Update, ArrayOfStructures);
111 void BM_PushBack_Baseline_StructureOfArrays(benchmark::State&
state) {
113 arrays.resize(kParticleCount);
115 new_arrays.reserve(kParticleCount);
116 for (
auto _ :
state) {
118 for (std::size_t i = 0; i < kParticleCount; ++i) {
119 new_arrays.states.push_back(State{});
120 new_arrays.weights.push_back(0);
121 new_arrays.clusters.push_back(0);
126 void BM_PushBack_Baseline_ArrayOfStructures(benchmark::State&
state) {
127 std::vector<Particle> particles;
128 particles.resize(kParticleCount);
129 std::vector<Particle> new_particles;
130 new_particles.reserve(kParticleCount);
131 for (
auto _ :
state) {
132 new_particles.clear();
133 for (std::size_t i = 0; i < kParticleCount; ++i) {
134 new_particles.emplace_back(std::get<0>(particles[i]), 0, 0);
139 template <
class Container>
140 void BM_PushBack(benchmark::State&
state) {
141 auto container = Container{};
142 container.resize(kParticleCount);
143 auto new_container = Container{};
144 new_container.reserve(kParticleCount);
145 for (
auto _ :
state) {
146 new_container.clear();
148 return std::make_tuple(
state, 0, 0);
153 BENCHMARK(BM_PushBack_Baseline_StructureOfArrays);
154 BENCHMARK_TEMPLATE(BM_PushBack, StructureOfArrays);
155 BENCHMARK(BM_PushBack_Baseline_ArrayOfStructures);
156 BENCHMARK_TEMPLATE(BM_PushBack, ArrayOfStructures);
158 void BM_Assign_Baseline_ArrayOfStructures(benchmark::State&
state) {
159 std::vector<Particle> particles;
160 particles.resize(kParticleCount);
161 std::vector<Particle> new_particles;
162 new_particles.resize(kParticleCount);
163 for (
auto _ :
state) {
164 for (std::size_t i = 0; i < kParticleCount; ++i) {
165 new_particles[i] = Particle{std::get<0>(particles[i]), 0, 0};
170 void BM_Assign_Baseline_StructureOfArrays(benchmark::State&
state) {
172 arrays.resize(kParticleCount);
174 new_arrays.resize(kParticleCount);
175 for (
auto _ :
state) {
176 for (std::size_t i = 0; i < kParticleCount; ++i) {
177 new_arrays.states[i] = arrays.states[i];
178 new_arrays.weights[i] = 0;
179 new_arrays.clusters[i] = 0;
184 template <
class Container>
185 void BM_Transform(benchmark::State&
state) {
186 auto container = Container{};
187 container.resize(kParticleCount);
188 auto new_container = Container{};
189 new_container.resize(kParticleCount);
190 for (
auto _ :
state) {
192 return std::make_tuple(
state, 0, 0);
197 template <
class Container>
198 void BM_AssignFromSized(benchmark::State&
state) {
199 auto container = Container{};
200 container.resize(kParticleCount);
201 auto new_container = Container{};
202 for (
auto _ :
state) {
203 new_container.assign_range(
205 ranges::views::transform([](
const State&
state) {
return std::make_tuple(
state, 0, 0); }));
209 template <
class Container>
210 void BM_AssignFromNonSized(benchmark::State&
state) {
211 auto container = Container{};
212 container.resize(kParticleCount);
213 auto new_container = Container{};
214 for (
auto _ :
state) {
215 new_container.assign_range(
217 ranges::views::filter([](
auto) {
return true; }) |
218 ranges::views::transform([](
const State&
state) {
return std::make_tuple(
state, 0, 0); }));
222 template <
class Container>
223 void BM_AssignFromNonSizedReserved(benchmark::State&
state) {
224 auto container = Container{};
225 container.resize(kParticleCount);
226 auto new_container = Container{};
227 new_container.reserve(kParticleCount);
228 for (
auto _ :
state) {
229 new_container.assign_range(
231 ranges::views::filter([](
auto) {
return true; }) |
232 ranges::views::transform([](
const State&
state) {
return std::make_tuple(
state, 0, 0); }));
236 BENCHMARK(BM_Assign_Baseline_StructureOfArrays);
237 BENCHMARK_TEMPLATE(BM_AssignFromSized, StructureOfArrays);
238 BENCHMARK_TEMPLATE(BM_AssignFromNonSized, StructureOfArrays);
239 BENCHMARK_TEMPLATE(BM_AssignFromNonSizedReserved, StructureOfArrays);
240 BENCHMARK_TEMPLATE(BM_Transform, StructureOfArrays);
241 BENCHMARK(BM_Assign_Baseline_ArrayOfStructures);
242 BENCHMARK_TEMPLATE(BM_Transform, ArrayOfStructures);