简体   繁体   中英

Filling vector with emplace_back vs. std::transform

It's oversimplified code with a simple vector and class.

class OutputClass
{
public:
OutputClass(int x, int y);
};

std::vector<OutputClass> Convert(std::vector<int> const &input)
{
    std::vector<OutputClass> res;
    res.reserve(input.size());
    //either (1)
    for (auto const &in : input)
        res.emplace_back(in, in*in);
    return res;
    //or something like (2)
    std::transform(input.begin(), 
                   input.end(), 
                   std::back_inserter(res), 
                   [](InputClass const &in){return OutputClass(in, in*in);});
    return res;
}  

Is there a difference in performance between those two options? Static analyzers often have a rule for replacing all raw loops with algorithms, but in this case, it seems to me that looping with emplace_back would be more efficient, as we don't need either copy or move. Or I'm wrong and they are equal in terms of performance and (2) is preferable in terms of good style and readability?

To find out whether one is significantly faster than the other in a particular use case, you can measure.

I see no benefit in enforcing the creation of vectors. Avoiding that dynamic allocation when it isn't needed can be quite good for performance. Here is an example where vectors are used, but that's not necessary:

OutputClass
convert(int in)
{
    return {in, in*in};
}

auto
convert_range(const auto& input)
{
    return std::ranges::transform_view(input, convert);
}

#include <vector>
int main()
{
    std::vector<int> input {1, 2, 3};
    auto r = convert_range(input);
    std::vector<OutputClass> output(r.begin(), r.end());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM