167 lines
4.5 KiB
C++
167 lines
4.5 KiB
C++
|
//
|
||
|
// immer: immutable data structures for C++
|
||
|
// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente
|
||
|
//
|
||
|
// This software is distributed under the Boost Software License, Version 1.0.
|
||
|
// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt
|
||
|
//
|
||
|
|
||
|
#pragma once
|
||
|
|
||
|
#include "benchmark/vector/common.hpp"
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
constexpr auto concat_steps = 10u;
|
||
|
|
||
|
template <typename Vektor,
|
||
|
typename PushFn=push_back_fn>
|
||
|
auto benchmark_concat()
|
||
|
{
|
||
|
return [] (nonius::chronometer meter)
|
||
|
{
|
||
|
auto n = meter.param<N>();
|
||
|
|
||
|
auto v = Vektor{};
|
||
|
for (auto i = 0u; i < n; ++i)
|
||
|
v = PushFn{}(std::move(v), i);
|
||
|
|
||
|
measure(meter, [&] {
|
||
|
return v + v;
|
||
|
});
|
||
|
};
|
||
|
}
|
||
|
|
||
|
template <typename Fn>
|
||
|
auto benchmark_concat_librrb(Fn maker)
|
||
|
{
|
||
|
return
|
||
|
[=] (nonius::chronometer meter) {
|
||
|
auto n = meter.param<N>();
|
||
|
auto v = maker(n);
|
||
|
measure(meter, [&] {
|
||
|
return rrb_concat(v, v);
|
||
|
});
|
||
|
};
|
||
|
}
|
||
|
|
||
|
template <typename Vektor,
|
||
|
typename PushFn=push_back_fn>
|
||
|
auto benchmark_concat_incr()
|
||
|
{
|
||
|
return
|
||
|
[] (nonius::chronometer meter)
|
||
|
{
|
||
|
auto n = meter.param<N>();
|
||
|
|
||
|
auto v = Vektor{};
|
||
|
for (auto i = 0u; i < n / concat_steps; ++i)
|
||
|
v = PushFn{}(std::move(v), i);
|
||
|
|
||
|
measure(meter, [&] {
|
||
|
auto r = Vektor{};
|
||
|
for (auto i = 0u; i < concat_steps; ++i)
|
||
|
r = r + v;
|
||
|
return r;
|
||
|
});
|
||
|
};
|
||
|
}
|
||
|
|
||
|
template <typename Vektor>
|
||
|
auto benchmark_concat_incr_mut()
|
||
|
{
|
||
|
return
|
||
|
[] (nonius::chronometer meter)
|
||
|
{
|
||
|
auto n = meter.param<N>();
|
||
|
|
||
|
auto v = Vektor{}.transient();
|
||
|
for (auto i = 0u; i < n / concat_steps; ++i)
|
||
|
v.push_back(i);
|
||
|
|
||
|
measure(meter, [&] (int run) {
|
||
|
auto r = Vektor{}.transient();
|
||
|
for (auto i = 0u; i < concat_steps; ++i)
|
||
|
r.append(v);
|
||
|
return r;
|
||
|
});
|
||
|
};
|
||
|
}
|
||
|
|
||
|
template <typename Vektor>
|
||
|
auto benchmark_concat_incr_mut2()
|
||
|
{
|
||
|
return
|
||
|
[] (nonius::chronometer meter)
|
||
|
{
|
||
|
auto n = meter.param<N>();
|
||
|
|
||
|
using transient_t = typename Vektor::transient_type;
|
||
|
using steps_t = std::vector<transient_t, gc_allocator<transient_t>>;
|
||
|
auto vs = std::vector<steps_t, gc_allocator<steps_t>>(meter.runs());
|
||
|
for (auto k = 0u; k < vs.size(); ++k) {
|
||
|
vs[k].reserve(concat_steps);
|
||
|
for (auto j = 0u; j < concat_steps; ++j) {
|
||
|
auto vv = Vektor{}.transient();
|
||
|
for (auto i = 0u; i < n / concat_steps; ++i)
|
||
|
vv.push_back(i);
|
||
|
vs[k].push_back(std::move(vv));
|
||
|
}
|
||
|
}
|
||
|
measure(meter, [&] (int run) {
|
||
|
auto& vr = vs[run];
|
||
|
auto r = Vektor{}.transient();
|
||
|
assert(vr.size() == concat_steps);
|
||
|
for (auto i = 0u; i < concat_steps; ++i)
|
||
|
r.append(std::move(vr[i]));
|
||
|
return r;
|
||
|
});
|
||
|
};
|
||
|
}
|
||
|
|
||
|
template <typename Vektor>
|
||
|
auto benchmark_concat_incr_chunkedseq()
|
||
|
{
|
||
|
return
|
||
|
[] (nonius::chronometer meter)
|
||
|
{
|
||
|
auto n = meter.param<N>();
|
||
|
|
||
|
using steps_t = std::vector<Vektor>;
|
||
|
auto vs = std::vector<steps_t>(meter.runs());
|
||
|
for (auto k = 0u; k < vs.size(); ++k) {
|
||
|
for (auto j = 0u; j < concat_steps; ++j) {
|
||
|
auto vv = Vektor{};
|
||
|
for (auto i = 0u; i < n / concat_steps; ++i)
|
||
|
vv.push_back(i);
|
||
|
vs[k].push_back(std::move(vv));
|
||
|
}
|
||
|
}
|
||
|
measure(meter, [&] (int run) {
|
||
|
auto& vr = vs[run];
|
||
|
auto r = Vektor{};
|
||
|
for (auto i = 0u; i < concat_steps; ++i)
|
||
|
r.concat(vr[i]);
|
||
|
return r;
|
||
|
});
|
||
|
};
|
||
|
}
|
||
|
|
||
|
template <typename Fn>
|
||
|
auto benchmark_concat_incr_librrb(Fn maker)
|
||
|
{
|
||
|
return
|
||
|
[=] (nonius::chronometer meter) {
|
||
|
auto n = meter.param<N>();
|
||
|
auto v = maker(n / concat_steps);
|
||
|
measure(meter, [&] {
|
||
|
auto r = rrb_create();
|
||
|
for (auto i = 0ul; i < concat_steps; ++i)
|
||
|
r = rrb_concat(r, v);
|
||
|
return r;
|
||
|
});
|
||
|
};
|
||
|
}
|
||
|
|
||
|
} // anonymous namespace
|