Monday, June 11, 2012

Does inverting the "if' improve performance?


I've been using ReSharper for a while now and sometimes it suggests that I invert the if . I guess an example would be a better explanation of my situation:




public void myfunction(int exampleParam){
if(exampleParam > 0){
//Do something with form controls for example.
}
}



Now ReSharper suggests that I invert the if to this:




public void myfunction(int exampleParam){
if(exampleParam <= 0)
return;
//Do something with form controls for example
}



Does this "improve" performance somehow? Or is it just aesthetic?


Source: Tips4all

9 comments:

  1. It is not only aesthetic, but it also reduces the maximum nesting level inside the method. This is generally regarded as a plus because it makes methods easier to understand (and indeed, many static analysis tools provide a measure of this as one of the indicators of code quality).

    On the other hand, it also makes your method have multiple exit points, something that another group of people believes is a no-no.

    Personally, I agree with ReSharper and the first group (in a language that has exceptions I find it silly to discuss "multiple exit points"; almost anything can throw, so there are numerous potential exit points in all methods).

    Regarding performance: both versions should be equivalent (if not at the IL level, then certainly after the jitter is through with the code) in every language. Theoretically this depends on the compiler, but practically any widely used compiler of today is capable of handling much more advanced cases of code optimization than this.

    ReplyDelete
  2. As others have mentioned, there shouldn't be a performance hit, but there are other considerations. Aside from those valid concerns, this also can open you up to gotchas in some circumstances. Suppose you were dealing with a double instead:

    public void myfunction(double exampleParam){
    if(exampleParam > 0){
    //Body will *not* be executed if Double.IsNan(exampleParam)
    }
    }


    Contrast that with the seemingly equivalent inversion:

    public void myfunction(double exampleParam){
    if(exampleParam <= 0)
    return;
    //Body *will* be executed if Double.IsNan(exampleParam)
    }


    So in certain circumstances what appears to be a a correctly inverted if might not be.

    ReplyDelete
  3. It doesn't only affect aesthetics, but it also prevents code nesting. It can actually functioning as a precondition to ensure that your data is valid as well.

    ReplyDelete
  4. Performance-wise, there will be no noticeable difference between the two approaches.

    But coding is about more than performance. Clarity and maintainability are also very important. And, in cases like this where it doesn't affect performance, it is the only thing that matters.

    There are competing schools of thought as to which approach is preferable.

    One view is the one others have mentioned: the second approach reduces the nesting level, which improves code clarity. This is natural in an imperative style: when you have nothing left to do, you might as well return early.

    Another view, from the perspective of a more functional style, is that a method should have only one exit point. Everything in a functional language is an expression. So if statements must always have an else clauses. Otherwise the if expression wouldn't always have a value. So in the functional style, the first approach is more natural.

    ReplyDelete
  5. I'd like to add that there is name for those inverted if's - Guard Clause. I use it whenever I can.

    I hate reading code where there is if at the beginning, two screens of code and no else. Just invert if and return. That way nobody will waste time scrolling.

    http://c2.com/cgi/wiki?GuardClause

    ReplyDelete
  6. Performance is in two parts. You have performance when the software is in production, but you also want to have performance while developing and debugging. The last thing a developer wants is to "wait" for something trivial. In the end, compiling this with optimization enabled will result in similar code. So it's good to know these little tricks that pay off in both scenarios.

    The case in the question is clear, ReSharper is correct. Rather than nesting if statements, and creating new scope in code, you're setting a clear rule at the start of your method. It increases readability, it will be easier to maintain, and it reduces the amount of rules one has to sift through to find where they want to go.

    ReplyDelete
  7. In theory, inverting if could lead to better performance if it increases branch prediction hit rate. In practice, I think it it very hard to know exactly how branch prediction will behave, especially after compiling, so I would not do it in my day to day development, except if I am writing assembly code.

    More on branch prediction here.

    ReplyDelete
  8. Avoiding multiple exit points can lead to performance gains. I am not sure about C# but in C++ the Named Return Value Optimization (Copy Elision, ISO C++ '03 12.8/15) depends on having a single exit point. This optimization avoids copy constructing your return value (in your specific example it doesn't matter). This could lead to considerable gains in performance in tight loops, as you are saving a constructor and a destructor each time the function is invoked.

    But for 99% of the cases saving the additional constructor and destructor calls is not worth the loss of readability nested if blocks introduce (as others have pointed out).

    ReplyDelete
  9. ReSharper's suggestions are only suggestions and not errors or warnings. In almost all cases of suggestions it is up to you to decide which code you prefer.
    The advantage of the suggestions is that you can switch to the other possibility just by Alt+Enter and Enter.

    ReplyDelete