1

if we have if statements with declarations of variables like this:

#include <iostream>
#include <ctime>

using namespace std;

int main() {

    int res = 0;

    clock_t begin = clock();
    for(int i=0; i<500500000; i++) {
        if(i%2 == 0) {int fooa; fooa = i;}
        if(i%2 == 0) {int foob; foob = i;}
        if(i%2 == 0) {int fooc; fooc = i;}
    }
    clock_t end = clock();
    double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

    cout << elapsed_secs << endl;

    return 0;
}

the result is:

1.44

Process returned 0 (0x0)   execution time : 1.463 s
Press any key to continue.

but, if it is:

#include <iostream>
#include <ctime>

using namespace std;

int main() {

    int res = 0;

    clock_t begin = clock();
    for(int i=0; i<500500000; i++) {
        res++;
        res--;
        res++;
    }
    clock_t end = clock();
    double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;

    cout << elapsed_secs << endl;

    return 0;
}

the result is:

3.098

Process returned 0 (0x0)   execution time : 3.115 s
Press any key to continue.

why does adding or subtracting takes more time to run than a if statement with a variable declaration?

Nicolas Caous
  • 703
  • 5
  • 18
  • 5
    Because the if statement with the variable declaration does literally nothing and therefore it does not exist. E: though now that I look at it, neither of those loops do anything at all, so in order to get any elapsed time you must have compiled this with optimizations suppressed. That makes the result meaningless, but it also means my initial guess does not apply. – harold Mar 05 '17 at 03:26
  • 2
    Check your assembly code to see effect of optimization. – MikeCAT Mar 05 '17 at 03:26
  • [Here's an example of how pre and post incrementors work in C](https://www.quora.com/How-do-the-increment-and-decrement-operators-work-in-C) – user82395214 Mar 05 '17 at 03:30
  • It's not useful to look at runtime of code generated when the compiler is crippled by disabling optimization. Try again with `-O2` or `/O2`. – Ben Voigt Mar 05 '17 at 03:30
  • Your test is completely meaningless. The compiler is entitled to eliminate the first loop entirely, regardless of whether optimization is specified, under the 'as-if' rule. – user207421 Mar 05 '17 at 03:41
  • I'm surprised the first one took 1 sec. It should be totally ignored because fooa/b/c are not used. – smttsp Mar 05 '17 at 04:17
  • @EJP I would be surprise to see the whole loop eliminated. There are cases where I could need an endless loop to be performed without any effect. Are you saying that a statement like "while(1);" can be completely removed by compiler optimization? – Jack Mar 05 '17 at 08:26
  • @Jack actually [they can](http://stackoverflow.com/a/24284388/555045), but it's irrelevant to this situation: these loops clearly terminate, so eliminating them does not risk making previously unreachable code reachable. – harold Mar 05 '17 at 14:01

1 Answers1

1

The difference is almost certainly due to compiler optimization. You’ll have to look at the assembly to make sure, but here is my take on what happens:

In the first example it’s trivial for the optimizer to realize that the bodies of the ifs have no effect. In each a variable local to the if is declared, assigned to and immediately destroyed. So the ifs get optimized away, leaving an empty for loop that gets optimized away as well.

The sitiuation in the second example is not that trivial on the whole. What is trivial is that the body of the loop boils down to a single res++, which most likely will be further optimized to ++res. But because res is not local to the loop the optimizer has to consider the whole main() function to realize that the loop has no effect. Most likely it fails to do so.

Conclusion: In its current form the measurements are meaningless. Disabling optimization also won’t help because you’ll never do that for a production build. If you really want to dive into this I suggest watching CppCon 2015: Chandler Carruth "Tuning C++: Benchmarks, and CPUs, and Compilers! Oh My!" for great advice on how to handle the optimizer in these kinds of siutuations.

besc
  • 2,507
  • 13
  • 10