Optimization of if

Discussion in 'C Programming' started by Rajen, Feb 1, 2007.

  1. Rajen

    Rajen Guest

    Hi all,
    I have a code like this.
    if(X)
    {
    return retVal1;
    }

    if(Y)
    {
    return retVal2;
    }

    if(Z)
    {
    return retVal3;
    }


    The above if can be written like this
    int retVal = 0;
    if(X)
    {
    retVal=retVal1;
    }

    if( retVal == 0)
    {
    if( Y)
    retVal=retVal2;
    }

    if( retVal == 0 )
    {
    if(Z)
    retVal=retVal3;
    }

    return retVal;
    which has only one exit point. But it has more If's

    How do i Optimize this? Please give me some suggestions.
    Rajen, Feb 1, 2007
    #1
    1. Advertising

  2. Rajen

    Chris Dollin Guest

    Rajen wrote:

    > Hi all,
    > I have a code like this.
    > if(X)
    > {
    > return retVal1;
    > }
    >
    > if(Y)
    > {
    > return retVal2;
    > }
    >
    > if(Z)
    > {
    > return retVal3;
    > }
    >
    >
    > The above if can be written like this
    > int retVal = 0;
    > if(X)
    > {
    > retVal=retVal1;
    > }
    >
    > if( retVal == 0)
    > {
    > if( Y)
    > retVal=retVal2;
    > }
    >
    > if( retVal == 0 )
    > {
    > if(Z)
    > retVal=retVal3;
    > }
    >
    > return retVal;
    > which has only one exit point. But it has more If's
    >
    > How do i Optimize this? Please give me some suggestions.


    Optimise? What's to optimise? I didn't see anything non-optimal
    with the first one. (There's a missing case for when none of
    X, Y, and Z are true.) The second form seems to assume that
    neither `retVal1` nor `retVal2` are 0. Maybe that's true but
    it seems to be asking for trouble to rely on it. And that second
    form is clumsier and harder to understand.

    Myself I prefer the form:

    return
    X ? retVal1
    : Y ? retVal2
    : Z ? retVal3
    : whateverYouWantForNoneOfXYZ
    ;

    laid out in whatever way fits your coding style.

    Optimisation? This is really the bottleneck in your code? Colour
    me gobsmacked.

    --
    Chris "green/purple hedgehog" Dollin
    "We live for the One, you die for the One." Unsaid /Babylon 5/.
    Chris Dollin, Feb 1, 2007
    #2
    1. Advertising

  3. In article <>,
    Rajen <> wrote:

    > I have a code like this.
    > if(X)
    > {
    > return retVal1;
    > }
    >
    > if(Y)
    > {
    > return retVal2;
    > }
    >
    > if(Z)
    > {
    > return retVal3;
    > }
    >
    >
    >The above if can be written like this
    > int retVal = 0;
    > if(X)
    > {
    > retVal=retVal1;
    > }
    >
    > if( retVal == 0)
    > {
    > if( Y)
    > retVal=retVal2;
    > }
    >
    > if( retVal == 0 )
    > {
    > if(Z)
    > retVal=retVal3;
    > }
    >
    > return retVal;
    >which has only one exit point. But it has more If's


    Your first form is much clearer, so use that. If your employer insists on
    less clear code to satisfy some rules, find another employer.

    -- Richard
    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
    Richard Tobin, Feb 1, 2007
    #3
  4. Rajen wrote:
    > Hi all,
    > I have a code like this.
    > if(X)
    > {
    > return retVal1;
    > }
    >
    > if(Y)
    > {
    > return retVal2;
    > }
    >
    > if(Z)
    > {
    > return retVal3;
    > }
    >


    > which has only one exit point. But it has more If's
    >
    > How do i Optimize this? Please give me some suggestions.


    Nothing says the first case generate more than one exit point of your
    function. BTW some compilers will effectively generate only one exit
    point and jump to it from each return point, so it far from obvious that
    first case will not be optimal. Clarity is much more important than
    implementation dependant low-level assumption.

    a+, ld.
    Laurent Deniau, Feb 1, 2007
    #4
  5. Rajen

    Eric Sosman Guest

    Rajen wrote:
    > Hi all,
    > I have a code like this.
    > if(X)
    > {
    > return retVal1;
    > }
    >
    > if(Y)
    > {
    > return retVal2;
    > }
    >
    > if(Z)
    > {
    > return retVal3;
    > }
    >
    >
    > The above if can be written like this
    > int retVal = 0;
    > if(X)
    > {
    > retVal=retVal1;
    > }
    >
    > if( retVal == 0)
    > {
    > if( Y)
    > retVal=retVal2;
    > }
    >
    > if( retVal == 0 )
    > {
    > if(Z)
    > retVal=retVal3;
    > }
    >
    > return retVal;
    > which has only one exit point. But it has more If's
    >
    > How do i Optimize this? Please give me some suggestions.


    First, it's extremely unlikely that any optimization
    is needed.

    Second, learn about the `else' keyword.

    --
    Eric Sosman
    lid
    Eric Sosman, Feb 1, 2007
    #5
  6. Rajen

    Chris Dollin Guest

    Laurent Deniau wrote:

    > Rajen wrote:
    >> Hi all,
    >> I have a code like this.
    >> if(X)
    >> {
    >> return retVal1;
    >> }
    >>
    >> if(Y)
    >> {
    >> return retVal2;
    >> }
    >>
    >> if(Z)
    >> {
    >> return retVal3;
    >> }
    >>

    >
    >> which has only one exit point. But it has more If's
    >>
    >> How do i Optimize this? Please give me some suggestions.

    >
    > Nothing says the first case generate more than one exit point of your
    > function.


    There are three exit points show: each return is an exit point.
    (It doesn't matter how the compiler compiles it [1]; I suspect
    the OP is afflicted by Code Style Rules that values Conformance
    over Clarity.)

    [1] EG the compiler [2] might translate `return 0;`, `return 1;`
    and `return -1;` to jumps into the implementation library
    code to load the constant and then return. One might then
    say there were /no/ exit points in a function with those
    return values ...

    [2] OK, it was an RTL/2 compiler, not a C compiler, optimising
    for space.

    --
    Chris "electric hedgehog" Dollin
    There' no hortage of vowel on Uenet.
    Chris Dollin, Feb 1, 2007
    #6
  7. Rajen

    Richard Bos Guest

    "Rajen" <> wrote:

    > if(X)
    > {
    > return retVal1;
    > }
    >
    > if(Y)
    > {
    > return retVal2;
    > }
    >
    > if(Z)
    > {
    > return retVal3;
    > }
    >
    > The above if can be written like this
    > int retVal = 0;
    > if(X)
    > {
    > retVal=retVal1;
    > }
    >
    > if( retVal == 0)
    > {
    > if( Y)
    > retVal=retVal2;
    > }
    >
    > if( retVal == 0 )
    > {
    > if(Z)
    > retVal=retVal3;
    > }
    >
    > return retVal;
    > which has only one exit point. But it has more If's
    >
    > How do i Optimize this? Please give me some suggestions.


    As others have noted, you're missing a default value.

    Try this:

    retval=default_value;
    if (Z) retval=retval3;
    if (Y) retval=retval2;
    if (X) retval=retval1;
    return retval;

    Then immediately return to the first, maintainable version, but lay it
    out a bit more legibly:

    if(X) return retVal1;
    if(Y) return retVal2;
    if(Z) return retVal3;

    or if you like braces:

    if(X) { return retVal1; }
    if(Y) { return retVal2; }
    if(Z) { return retVal3; }

    Richard
    Richard Bos, Feb 1, 2007
    #7
  8. "Rajen" <> wrote in message
    news:...
    > Hi all,
    > I have a code like this.
    > if(X)
    > {
    > return retVal1;
    > }
    >
    > if(Y)
    > {
    > return retVal2;
    > }
    >
    > if(Z)
    > {
    > return retVal3;
    > }
    >
    >
    > The above if can be written like this
    > int retVal = 0;
    > if(X)
    > {
    > retVal=retVal1;
    > }
    >
    > if( retVal == 0)
    > {
    > if( Y)
    > retVal=retVal2;
    > }
    >
    > if( retVal == 0 )
    > {
    > if(Z)
    > retVal=retVal3;
    > }
    >
    > return retVal;
    > which has only one exit point. But it has more If's


    You have three options for optimization.

    a)First, note in your second example that this is a control flow problem.
    Your problem is keeping the value of retVal from being multiply assigned.
    It is more economical to do this with an else-if statement, i.e.

    if (X)
    retVal = retVal1;
    else if (Y)
    retVal = retVal2;
    else
    retVal = retVal3;

    This suppresses the extra "0" tests and does what you want. Also, if your
    possibilities are mutually exclusive and/or exhaustive, you can suppress the
    final Z test.

    b)Else-if has the limit that in order to get to clause N, all of the
    preceding N tests must have been evaluated. If your problem is amenable to
    it, try using the switch() statement.

    c)Finally, in special cases where switch() can't be used, there are
    sometimes relationships that let one optimize. For example, assume that I
    want a fast implementation of floor(log_10(x)) up through 10,000. I could
    do it like this:

    if (x < 100)
    {
    if (x < 10)
    {
    }
    else
    {
    }
    }
    else
    {
    if (x < 1000)
    {
    }
    else
    {
    }
    }

    When the domain is "paneled", you can often build an if() construct where
    the time to reach the innermost clause is related to log(N) where N is the
    number of cases.

    Notice that the construct above gets there in 2 tests (rather than up to
    4).
    --
    David T. Ashley ()
    http://www.e3ft.com (Consulting Home Page)
    http://www.dtashley.com (Personal Home Page)
    http://gpl.e3ft.com (GPL Publications and Projects)
    David T. Ashley, Feb 1, 2007
    #8
  9. Rajen

    Default User Guest

    Rajen wrote:

    > Hi all,
    > I have a code like this.
    > if(X)
    > {
    > return retVal1;
    > }
    >
    > if(Y)
    > {
    > return retVal2;
    > }
    >
    > if(Z)
    > {
    > return retVal3;
    > }


    [snip]

    > How do i Optimize this? Please give me some suggestions.



    The more typical way to write this if you want to have only one return
    statement is with an if-else if ladder.

    int retVal = 0; /* or other default value */

    if(X)
    {
    retVal = retVal1;
    }
    else if(Y)
    {
    retVal = retVal2;
    }
    else if(Z)
    {
    retVal = retVal3;
    }

    return retVal;

    This method probably is about as efficient as the one with returns in
    the if() statements, understanding that such things are up to the
    implementation.

    You could also skip the initialization of retVal and put a terminating
    else that sets it to the "no hit" value, but I'd prefer the method
    above. If the return value must be one of the three, then set retVal to
    one of the values and use only two if()'s.




    Brian
    Default User, Feb 1, 2007
    #9
  10. (Richard Bos) writes:
    > "Rajen" <> wrote:
    > > if(X)
    > > {
    > > return retVal1;
    > > }
    > >
    > > if(Y)
    > > {
    > > return retVal2;
    > > }
    > >
    > > if(Z)
    > > {
    > > return retVal3;
    > > }

    [...]
    > As others have noted, you're missing a default value.
    >
    > Try this:
    >
    > retval=default_value;
    > if (Z) retval=retval3;
    > if (Y) retval=retval2;
    > if (X) retval=retval1;
    > return retval;


    That's likely to be (slightly) *less* efficient, since it can assign
    to retval multiple times. It can also behave differently if X, Y, and
    Z are expressions that depend on each other's evaluation; for example,
    evaluating Y might not work if X hasn't already been evaluated.

    > Then immediately return to the first, maintainable version, but lay it
    > out a bit more legibly:
    >
    > if(X) return retVal1;
    > if(Y) return retVal2;
    > if(Z) return retVal3;
    >
    > or if you like braces:
    >
    > if(X) { return retVal1; }
    > if(Y) { return retVal2; }
    > if(Z) { return retVal3; }


    I'd probably lay it out that way if the conditions and result
    expressions really were that terse, except that I always put a blank
    after an "if" (it's not a function call, so it shouldn't look like
    one):

    if (X) return retVal1;
    if (Y) return retVal2;
    if (Z) return retVal3;

    But in real life, everything is likely to be longer, perhaps too long
    to fit on a single line. And if the conditions really were "X", "Y",
    and "Z", I'd seriously consider using names that make some actual
    sense.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Feb 1, 2007
    #10
  11. Chris Dollin <> writes:
    > Laurent Deniau wrote:
    > > Rajen wrote:
    > >> Hi all,
    > >> I have a code like this.
    > >> if(X)
    > >> {
    > >> return retVal1;
    > >> }
    > >>
    > >> if(Y)
    > >> {
    > >> return retVal2;
    > >> }
    > >>
    > >> if(Z)
    > >> {
    > >> return retVal3;
    > >> }
    > >>

    > >
    > >> which has only one exit point. But it has more If's
    > >>
    > >> How do i Optimize this? Please give me some suggestions.

    > >
    > > Nothing says the first case generate more than one exit point of your
    > > function.

    >
    > There are three exit points show: each return is an exit point.
    > (It doesn't matter how the compiler compiles it [1]; I suspect
    > the OP is afflicted by Code Style Rules that values Conformance
    > over Clarity.)


    Possibly, but we don't really know that. The question was "How do i
    Optimize this?", not "How do I optimize this while conforming to
    certain code style rules that I haven't bothered to tell you you
    about?".

    There are real advantages in restricting yourself to a single exit
    point, but they show up more in maintenance than in performance. For
    example, if you later find that you need to perform some action before
    returning a value, given the above quoted code you need to do it in
    three places. If you instead save the result to a single variable,
    add "else"s, and return the value of the variable at the bottom, you
    can add the extra code in just one place.

    Whether this means you should *always* have just one exit point is a
    subject of considerable debate.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Feb 1, 2007
    #11
  12. On 1 Feb 2007 05:45:41 -0800, "Rajen" <> wrote:

    >Hi all,
    > I have a code like this.
    > if(X)
    > {
    > return retVal1;
    > }
    >
    > if(Y)
    > {
    > return retVal2;
    > }
    >
    > if(Z)
    > {
    > return retVal3;
    > }
    >
    >
    >The above if can be written like this
    > int retVal = 0;
    > if(X)
    > {
    > retVal=retVal1;
    > }
    >
    > if( retVal == 0)
    > {
    > if( Y)
    > retVal=retVal2;
    > }
    >
    > if( retVal == 0 )
    > {
    > if(Z)
    > retVal=retVal3;
    > }
    >
    > return retVal;
    >which has only one exit point. But it has more If's
    >
    >How do i Optimize this? Please give me some suggestions.



    I assume that you are asking how to optimize the clarity and
    maintainability of the code rather than speed. There have been many
    excellent answers. Here is a different kind of answer. :)

    int retval_index = 0;
    int retval[] = {retval_default, retval1, retval2, retval3};

    if (X) retval_index = 1;
    else if (Y) retval_index = 2;
    else if (Z) retval_index = 3;

    return retval[retval_index];
    Richard Harter, Feb 1, 2007
    #12
  13. Rajen

    CBFalconer Guest

    Richard Tobin wrote:
    > Rajen <> wrote:
    >
    >> I have a code like this.
    >> if(X)
    >> {
    >> return retVal1;
    >> }
    >>
    >> if(Y)
    >> {
    >> return retVal2;
    >> }
    >>
    >> if(Z)
    >> {
    >> return retVal3;
    >> }
    >>
    >>
    >> The above if can be written like this
    >> int retVal = 0;
    >> if(X)
    >> {
    >> retVal=retVal1;
    >> }
    >>
    >> if( retVal == 0)
    >> {
    >> if( Y)
    >> retVal=retVal2;
    >> }
    >>
    >> if( retVal == 0 )
    >> {
    >> if(Z)
    >> retVal=retVal3;
    >> }
    >>
    >> return retVal;
    >> which has only one exit point. But it has more If's

    >
    > Your first form is much clearer, so use that. If your employer
    > insists on less clear code to satisfy some rules, find another
    > employer.


    No, just write clearer and more compact code:

    int retval;

    if (X) retval = retval1;
    else if (Y) retval = retval2;
    else if (Z) retval = retval3;
    else retval = 0;
    return retval;

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>
    CBFalconer, Feb 1, 2007
    #13
  14. Keith Thompson wrote:
    >> retval=default_value;
    >> if (Z) retval=retval3;
    >> if (Y) retval=retval2;
    >> if (X) retval=retval1;
    >> return retval;

    >
    > That's likely to be (slightly) *less* efficient, since it can assign
    > to retval multiple times. It can also behave differently if X, Y, and
    > Z are expressions that depend on each other's evaluation; for example,
    > evaluating Y might not work if X hasn't already been evaluated.


    Agreed. Although any compiler written within the last 15 years will just
    optimize this out (provided optimization is turned on). The amount of time
    even I've just spent typing this message is more time than the difference
    would ever amount to in the long run.
    Christopher Layne, Feb 2, 2007
    #14
  15. Keith Thompson wrote:

    >> There are three exit points show: each return is an exit point.
    >> (It doesn't matter how the compiler compiles it [1]; I suspect
    >> the OP is afflicted by Code Style Rules that values Conformance
    >> over Clarity.)

    >
    > Possibly, but we don't really know that. The question was "How do i
    > Optimize this?", not "How do I optimize this while conforming to
    > certain code style rules that I haven't bothered to tell you you
    > about?".


    About the only way I can see optimizing this cascade is if the conditions X,
    Y, Z had varying levels of computational demand. Obviously, the correct
    optimization is to move the most common case to the top - provided the
    secondary and tertiary cases are not exception to the common case. But we
    don't know the OPs conditions.

    e.g. (and I know this is obvious to you Keith):

    if (compute_entire_disk_space_used() > 0)
    return retVal2;
    else if ((rand() + ((v & y) << 4)) % 78)
    return retVal1;
    else if (c > 0)
    return retVal3;

    I think it's obvious which changes should be made there.
    Christopher Layne, Feb 2, 2007
    #15
  16. Chris Dollin wrote:

    > Myself I prefer the form:
    >
    > return
    > X ? retVal1
    > : Y ? retVal2
    > : Z ? retVal3
    > : whateverYouWantForNoneOfXYZ
    > ;
    >
    > laid out in whatever way fits your coding style.


    Do you like pain?
    Christopher Layne, Feb 2, 2007
    #16
  17. Rajen

    Richard Guest

    CBFalconer <> writes:

    > Richard Tobin wrote:
    >> Rajen <> wrote:
    >>
    >>> I have a code like this.
    >>> if(X)
    >>> {
    >>> return retVal1;
    >>> }
    >>>
    >>> if(Y)
    >>> {
    >>> return retVal2;
    >>> }
    >>>
    >>> if(Z)
    >>> {
    >>> return retVal3;
    >>> }
    >>>
    >>>
    >>> The above if can be written like this
    >>> int retVal = 0;
    >>> if(X)
    >>> {
    >>> retVal=retVal1;
    >>> }
    >>>
    >>> if( retVal == 0)
    >>> {
    >>> if( Y)
    >>> retVal=retVal2;
    >>> }
    >>>
    >>> if( retVal == 0 )
    >>> {
    >>> if(Z)
    >>> retVal=retVal3;
    >>> }
    >>>
    >>> return retVal;
    >>> which has only one exit point. But it has more If's

    >>
    >> Your first form is much clearer, so use that. If your employer
    >> insists on less clear code to satisfy some rules, find another
    >> employer.

    >
    > No, just write clearer and more compact code:
    >
    > int retval;
    >
    > if (X) retval = retval1;
    > else if (Y) retval = retval2;
    > else if (Z) retval = retval3;
    > else retval = 0;
    > return retval;


    In commercial SW, multiple statements/expressions on a line are neither
    clearer nor more "compact". The layout above is horrible and totally
    debugger unfriendly. The excessive whitespace breaks the flow of a code
    read. the lack of indentation doesnt hilite the conditional
    assignments. 0 out of 10.
    Richard, Feb 2, 2007
    #17
  18. Richard wrote:

    >> if (X) retval = retval1;
    >> else if (Y) retval = retval2;
    >> else if (Z) retval = retval3;
    >> else retval = 0;
    >> return retval;

    >
    > In commercial SW, multiple statements/expressions on a line are neither
    > clearer nor more "compact". The layout above is horrible and totally
    > debugger unfriendly. The excessive whitespace breaks the flow of a code
    > read. the lack of indentation doesnt hilite the conditional
    > assignments. 0 out of 10.


    Pretty common style idiom for extremely simple maintenance logic. Get used to
    it. Obviously for a more complex case that is not filled with rudiment, you
    will see multiple lines. I just think you're pissed off at the "style"
    itself.
    Christopher Layne, Feb 2, 2007
    #18
  19. Rajen

    Nishu Guest

    On Feb 1, 6:45 pm, "Rajen" <> wrote:
    > Hi all,
    > I have a code like this.
    > if(X)
    > {
    > return retVal1;
    > }
    >
    > if(Y)
    > {
    > return retVal2;
    > }
    >
    > if(Z)
    > {
    > return retVal3;
    > }
    >

    <snip>
    > How do i Optimize this? Please give me some suggestions.


    Your first code is optimized in speed as well as size. What more
    optimizations do you need?

    -Nishu
    Nishu, Feb 2, 2007
    #19
  20. Rajen

    Nishu Guest

    On Feb 1, 7:18 pm, Eric Sosman <> wrote:
    > Rajen wrote:
    > > Hi all,
    > > I have a code like this.
    > > if(X)
    > > {
    > > return retVal1;
    > > }

    >
    > > if(Y)
    > > {
    > > return retVal2;
    > > }

    >
    > > if(Z)
    > > {
    > > return retVal3;
    > > }

    >
    > > The above if can be written like this
    > > int retVal = 0;
    > > if(X)
    > > {
    > > retVal=retVal1;
    > > }

    >
    > > if( retVal == 0)
    > > {
    > > if( Y)
    > > retVal=retVal2;
    > > }

    >
    > > if( retVal == 0 )
    > > {
    > > if(Z)
    > > retVal=retVal3;
    > > }

    >
    > > return retVal;
    > > which has only one exit point. But it has more If's

    >
    > > How do i Optimize this? Please give me some suggestions.

    >
    > First, it's extremely unlikely that any optimization
    > is needed.
    >
    > Second, learn about the `else' keyword.


    Is 'else' keyword really necessary? What is the drawback in using only
    if statements?

    Thanks,
    Nishu
    Nishu, Feb 2, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JE
    Replies:
    0
    Views:
    449
  2. Andrew Greensted

    Don't care and optimization

    Andrew Greensted, Jan 10, 2006, in forum: VHDL
    Replies:
    3
    Views:
    3,137
    Andrew Greensted
    Jan 11, 2006
  3. Replies:
    0
    Views:
    506
  4. Pete Wright

    Re: Code optimization...

    Pete Wright, Jul 5, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    367
    David Waz...
    Jul 6, 2003
  5. Ravikiran

    Zero Optimization and Sign Optimization???

    Ravikiran, Nov 17, 2008, in forum: C Programming
    Replies:
    22
    Views:
    842
    Thad Smith
    Nov 24, 2008
Loading...

Share This Page