简体   繁体   中英

Performance with clean code in mind, what is better

For the cleanness of a for loop I like the range-based for loop. Inside the for loop I want to fill a vector of which I know the size before hand, but I am missing an index value. I now have two methods of doing it, declare a vector and add elements with push_back or create an initialized vector (should be faster right since no allocation is needed?), calculate the index and insert an element.

Question: What is the performance drawback of one over the other and/or are there better implementations.

Below the example code for this, the real code contains a relative small number of items (less than 10 presumably) but it will run through this procedure millions of times.

    //The vector as input for the for loop
    std::vector<double> vecIn = { 1, 2, 3, 4, 5 };

    //Adding values to vectors, vector size changes on each loop right?
    std::vector<double> vecOut1;
    //Loop through vector with range looping
    for (auto& val : vecIn) {
        vecOut1.push_back(val); //In reality val is some calculated value based on the input.
    }

    //Adding values to initialized vector, but need to calculate index.
    std::vector<double> vecOut2(vecIn.size());
    //Loop through vector with range looping
    for (auto& val : vecIn) {
        auto i = &val - &vecIn[0];
        vecOut2[i] = val;  //In reality val is some calculated value based on the input.
    }

I like the first loop for the shortness, but a afraid that preformance wise is will be worse.

Of course I can also declare an index at the beginning of the loop and iterate it but that seems to defeat the purpose of cleanness a bit.

EDIT: To clarify, this is demo code where I copy one vector into another. In the real program the input vector is processed and new values are calculated based on the input vector. The new values need to be inserted/appended to the vector output. In the real code the input is not even a vector but a boost::ublas::matrix.

It is pretty much the same.

You can let the compiler optimize things for you by doing:

std::vector<double> vecOut1(vecIn.begin(), vecIn.end());

or

std::vector<double> vecOut1 = vecIn

By doing this you are copying vecIn to vecOut1.

Another advise: Whether you can tell the type you are dealing with in for loops, avoid the use of keyword auto , and specify the type.

EDIT: As OP question was unclear, here is a new answer.

Your first aproach is just fine. There are some good alternatives too.

If you know the size of your vecOut2 vector before inserting elements you can have index accessing in a better way:

std::vector<double> vecOut2(vecIn.size());
for(int i = 0;i < vecOut2.size(); i++){
   vecOut2[i] = vecIn[i] + /* Your calculation */;
}

This really depends on how do you want to perform your calculation, and if the calculation is linear (if you have to jump between indexes or not).

All your first loop needs is a .reserve() to play in the same performance order of magnitude as the second one:

std::vector<double> vecOut1;
vecOut1.reserve(vecIn.size());
for (auto& val : vecIn) 
    vecOut1.push_back(val); 

reserve preallocates the requested elements without changing the vectors size - so there's no reallocation going on in the loop.

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