开发者

Taking vector size() out of loop condition to optimize

fibs is a std::vector. Using g++, I was 开发者_Go百科advised to take fibs.size() out of the loop, to save computing it each time (because the vector could change)

int sum = 0;
for(int i = 0; i < fibs.size(); ++i){
    if(fibs[i] % 2 == 0){
        sum += fibs[i];
    }
}

Surely there is some dataflow analysis in the compiler that would tell us that fibs won't change size. Is there? Or should I set some other variable to be fibs.size() and use that in the loop condition?


The compiler will likely determine that it won't change. Even if it did, size() for vectors is an O(1) operation.


Unless you know it's a problem, leave it as it is. First make it correct, then make it clear, then make it fast (if necessary).

vector::size is extremely fast anyway. It seems to me likely that the compiler will optimise this case, since it is fairly obvious that the vector is not modified and all the functions called will be inlined so the compiler can tell.

You could always look at the generated code to see if this has happened.

If you do want to change it, you need to be able to measure the time it takes before and after. That's a fair amount of work - you probably have better things to do.


size() is constant time operation, there's no penalty calling it this way. If you are concerned about performance and a more general way to go through the collection, use iterators:

int sum = 0;
for(auto it = fibs.cbegin(); it != fibs.cend(); ++it) {
    if((*it) % 2 == 0){
        sum += *it;
    }
}


I think you are missing another, more important point here: Is this loop causing a slow-down of your application? If you do not know for sure (i.e. if you haven't profiled), you risk focusing on the wrong parts of your application.

You already have to keep thousands of things in your head when writing programs (coding guidelines, architecture (bigger picture) of your application, variable names, function names, class names, readability, etc.), you can ignore the speed of the code during your initial implementation (in at least 95% of the time). This will allow you to focus on things, which are more important and far more valuable (like correctness, readability and maintainability).


In your example the compiler can easily analyze the flow and determine that it doesn't change. In more complicated code it cannot:

for(int i = 0; i < fibs.size(); ++i){
    complicated_function();
}

complicated_function can change fibs. However, since the above code involves a function call, the compiler cannot store fibs.size() in a register and hence you cannot eliminate the memory access.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜