RedditPP Mascot

RedditPP

r/cpp_questions • … • u/not_a_novel_account

std::back_inserter performance seems disastrous?

I would love to be able to pass around `std::output_iterator`s instead of having to pass whole collections and manually resize them when appending, but a few simple benchmarks of `std::back_inserter` seems like it has totally unaccpetable performance? Am I doing something wrong here?

Example functions:

void a(std::vector<std::uint8_t>& v, std::span<std::uint8_t> s) { auto next = v.size(); v.resize(v.size() + s.size()); std::memcpy(v.data() + next, s.data(), s.size()); }

void b(std::vector<std::uint8_t>& v, std::span<std::uint8_t> s) { auto next = v.size(); v.resize(v.size() + s.size()); std::ranges::copy(s, v.begin() + next); }

void c(std::vector<std::uint8_t>& v, std::span<std::uint8_t> s) { std::copy(s.begin(), s.end(), std::back_inserter(v)); }

void d(std::vector<std::uint8_t>& v, std::span<std::uint8_t> s) { std::ranges::copy(s, std::back_inserter(v)); }

Obviously this would be more generic in reality, but making everything concrete here for the purpose of clarity.

Results:

./bench a 0.02s user 0.00s system 96% cpu 0.020 total ./bench b 0.01s user 0.00s system 95% cpu 0.015 total ./bench c 0.17s user 0.00s system 99% cpu 0.167 total ./bench d 0.19s user 0.00s system 99% cpu 0.190 total

`a` and `b` are within noise of one another, as expected, but `c` and `d` are _really bad_?

Benchmark error? Missed optimization? Misuse of `std::back_inserter`? Better possible approaches for appending to a buffer?

Full benchmark code is here: https://gist.github.com/nickelpro/1683cbdef4cfbfc3f33e66f2a7db55ae

— 0