4 ms·
You can get another 56% speedup on the reserve()+emplace_back() version just by replacing (Widget widget) with (const Widget& widget) in the function declaratio
by LegionMammal978 2y ago
You can get another 56% speedup on the reserve()+emplace_back() version just by replacing (Widget widget) with (const Widget& widget) in the function declaration [0], more of a difference than any of the loops. As well as a further 39% speedup by moving transformed_data into repsonse.data instead of copying it [1]. My takeaway is that C++ makes it extremely easy to copy data around unnecessarily. Also, you should always profile your code for easy wins before making drastic changes.
[0] https://quick-bench.com/q/1Lcfho3hZW2DVgse3xkn82hZsFg https://quick-bench.com/q/1Lcfho3hZW2DVgse3xkn82hZsFg
[1] https://quick-bench.com/q/r0DxLEPK68VhBPect3qAhkNIVnA https://quick-bench.com/q/r0DxLEPK68VhBPect3qAhkNIVnA
- jeffbee 2y agoIn this degenerate example, the completely straightforward way is tied for fastest as well. It's clear this has nothing to do with ranges. Response response; response.data.reserve(widget.data.size()); std::ranges::transform(widget.data, std::back_inserter(response.data), [](const auto& element) { return ToData{.title = element.title, .amount = element.amount*42};}); return response;
- vitus 2y ago> the completely straightforward way is tied for fastest as well. Is it, though? back_inserter should replicate push_back(), which incurs a move at the very minimum. The approach with emplace_back() does not. https://quick-bench.com/q/1zwemArsS0gtKwveR9FZsuRwT34 https://quick-bench.com/q/1zwemArsS0gtKwveR9FZsuRwT34 This also isn't the way C++20 wants us to work with ranges and views, either -- this is basically just std::transform as you'd write it 20 years ago, except with a container as the argument instead of your begin / end iterators (so, basically absl::c_transform).
- deleted 2y ago[deleted]
- jeffbee 2y agoThe difference is in your file you still have the `Widget widget` parameter, whereas your faster version has the `const Widget& widget` parameter. That's what matters. ETA: there is a slight advantage for your function body using GNU libstdc++, but there is no advantage when using LLVM libc++. Under libc++ all three are exactly as fast, and faster across the board than any of the GNU results. https://quick-bench.com/q/Ot1AK-q7D0CNVDeHrKCRtJ-dmA0 https://quick-bench.com/q/Ot1AK-q7D0CNVDeHrKCRtJ-dmA0