Function Efficiency Question

Does anyone happen to know if there is a difference between the following two functions at run time?

void Func1()
{
if( false );
}

and

void Func2()
{
if( false )
{
// 1,000 lines of code here that are never called
}
}
They compile identically as the example you've given
One thing to consider when comparing snippets of code is compiler optimization - your code may be re-factored a bit by the compiler to make the code run faster. That said, the way "if" is implemented is that if the expression evaluates to false, the execution pointer (think of it as a pointer to the current line in code being executed) is set to the location at the end of the statement. To illustrate:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void Func1()
{
	bool bMyBool = false;
	
	if (bMyBool)
	{
		/* thousand lines of code */
	}

	// The above is the same as:

	if (!bMyBool)
	{
		goto NEXT;		
	}
	
	/* thousand lines of code */

NEXT:
}


The latter is what the generated assembly will do (if I recall correctly), and will jump to 'NEXT', which is just a memory address, and takes a set amount of time regardless of how far down the code NEXT is. So no, the two functions should run at about the same speed.
Every mainstream C++ compilers has some level of support for dead code elimination.
http://en.wikipedia.org/wiki/Dead_code_elimination

So, one would be surprised if the code generated (with optimizations enabled) for:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int foo( int a,  int b,  int c )
{
    if( false )
    {
        // dead code
        a = b + c ;
        int d = a + 6 ;
        ++a ;
        --b ;
        ++c ;
        d -= b ;
        if( d < c )
        {
            for( int i =0 ; i < 100 ; ++i ) d *= i%3 ;
            d = 45678 ;
        }
        return d-c ;
    }
    else return 6 ;
}

Wasn't equivalent to:
1
2
3
4
int foo( int a,  int b,  int c )
{
    return 6 ;
}

For instance, g++ 4.8 with -O3 -fomit-frame-pointer -c -S
1
2
3
__Z3fooiii:
	movl	$6, %eax
	ret


For this, there would be a quality of implementation issue involved:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
int bar( int a,  int b,  int c )
{
    if( (a<10) && (a>0) && (b>10) && (b<20) && (c<10) && (c>0) )
    {
        a = b + c ;
        int d = a + 6 ;
        ++a ;
        --b ;
        ++c ;
        d -= b ;
        if( d < c )
        {
            for( int i =0 ; i < 100 ; ++i ) d *= i%3 ;
            d = 45678 ;
        }
        return d-c ;
    }
    else return 6 ;
}


An aggressively optimizing compiler can use contant-folding, def-use analysis and dead-code elimination to arrive at:
1
2
3
4
int foo( int a,  int b,  int c )
{
    return 6 ;
}

But there is a lot the optimizer has to do; the analysis would have to be something like:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int bar( int a,  int b,  int c )
{
    if( (a<10) && (a>0) && (b>10) && (b<20) && (c<10) && (c>0) ) // a,b,c are non-negetive
    {
        //const  int a1 = a, b1 = b, c1 = c ;
        a = b + c ; // a == b1 + c1, will not overflow
        int d = a + 6 ; // d == b1 + c1 + 6, will not overflow
        ++a ; // a == b1 + c1 + 1 // never used
        --b ; // b == b1 - 1, will not underflow
        ++c ; // c == c1 + 1, will not overflow
        d -= b ; // d = b1 + c1 + 6 - (b1-1) == c1 + 7, will not overflow
        if( d < c ) // (c1+7) < (c1+1) == false
        {
            for( int i =0 ; i < 100 ; ++i ) d *= i%3 ; // dead code
            d = 45678 ; // dead code
        }
        return d-c ; // d-c == c1+7 - (c1+1) == 6 // constant folding
    }
    else return 6 ;
    // a, b, c, d are never used again
}


Topic archived. No new replies allowed.