Search Unity

elseif{ } vs else { if { } }

Discussion in 'Scripting' started by tcz8, Mar 16, 2019.

  1. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    In this exact use case, beside aesthetics and readability, is there any reason to use one or the other?

    Code A:
    Code (CSharp):
    1. void Update()
    2. {
    3.     if (conditionA)
    4.     {
    5.         ExampleFunction();
    6.     }
    7.     else if (conditionB)
    8.     {
    9.         AnotherExampleFunction();
    10.     }
    11. }
    Code B:
    Code (CSharp):
    1. void Update()
    2. {
    3.     if (conditionA)
    4.     {
    5.         ExampleFunction();
    6.     }
    7.     else
    8.     {
    9.         if (conditionB)
    10.         {
    11.             AnotherExampleFunction();
    12.         }
    13.     }
    14. }
    I know Code B allows inserting code in the else statement but outside the 2nd if but performance wise its the exact same thing once compiled right?

    Basic stuff I know... please humor me.

    Thanks for reading.
     
    Last edited: Mar 16, 2019
  2. WheresMommy

    WheresMommy

    Joined:
    Oct 4, 2012
    Posts:
    890
    If you do not ask for code logics and just the cost of those two snippets, I think they are the same. The rest depends on the situation if it is called or not, but if we just have conA and B true, I guess it would be the same.
     
  3. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
    This kind of optimization is often the one which yields the least benefits and it's called micro-optimization.

    My recommendation is to always use a Profiler to find where to look for optimization opportunities. Always concentrate on the top/slowest code-paths before micro optimizing things that perhaps don't need optimization.

    Here are a few links that should help you get started with the Unity profiler and performance optimization in Unity.

    Introduction to the Profiler
    https://unity3d.com/learn/tutorials/topics/interface-essentials/introduction-profiler

    Performance Optimization
    https://unity3d.com/learn/tutorials/topics/performance-optimization

    Practical guide to optimization for mobiles
    https://docs.unity3d.com/Manual/MobileOptimizationPracticalGuide.html


     
    DrZwieback and Ryiah like this.
  4. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,778
    In B case, you add another instruction, which need be executed. You probably wont see any, to neglecting difference even with million iteration.

    However, your choice may be more significant, if you start adding multiple else if conditions. Then you also may consider, if switch is better alternative.
     
    Last edited: Mar 19, 2019
  5. ihgyug

    ihgyug

    Joined:
    Aug 5, 2017
    Posts:
    194
    I think code B is slightly slower due to the extra instruction (the else). The if and else if instead should be the same performance wise in this example.
     
  6. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    Hi guys, you pretty much confirmed what I thought. @Peter77 You are completely right about this being useless optimisation. I wouldn't go over any code to change it but while coding I may start using else if now.

    I just remembered reading so much hate about using "else if" that I just stopped using it. But as @Antypodish mentioned it all depends on the usage and at some point its allways good to call it quit an pull out a switch statement.

    Thank you!
     
  7. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    It's always been my understanding that "else if" is not a special thing, but is literally just "else" followed by "if".

    Normally, when you write an "if" or an "else", you use curly braces to mark out the conditional code; e.g.
    Code (CSharp):
    1. else
    2. {
    3.     x = 7;
    4. }
    But the curly braces are just a way of telling the compiler to group a collection of statements as if they were a single statement. If you only want to execute a single statement anyway, it is completely legal (although stylistically dubious) to say:
    Code (CSharp):
    1. else
    2.     x = 7;
    That has exactly the same meaning. And since the amount of whitespace doesn't matter either, that's the same as writing
    Code (CSharp):
    1. else x = 7;


    Therefore,
    Code (CSharp):
    1. else if (y == 3) {...}
    means exactly the same thing as
    Code (CSharp):
    1. else
    2.     if (y == 3) {...}
    which means exactly the same thing as
    Code (CSharp):
    1. else
    2. {
    3.     if (y == 3) {...}
    4. }
    I don't think the compiler even notices that those are different.
     
    Last edited: Mar 19, 2019
  8. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,778
    In specific cases, may means the same, by what human reads, but without compiler explicit optimization, compiled code behaves different.

    Code (CSharp):
    1. if
    2. { ... }
    3. else
    4. {
    5.   if
    6.   { ... }
    7.   else
    8.   { ... }
    9. }
    is not the same, what

    Code (CSharp):
    1. if
    2. { ... }
    3. else if
    4. { ... }
    5. else
    6. { ... }
    7.  
    This become more obvious, if more else if nested statements are in the loop.

    For example
    Code (CSharp):
    1. if
    2. { ... }
    3. else if
    4. {
    5.   if
    6.   { ... }
    7.   else
    8.   { ... }
    9. }
    10. else
    11. {
    12.   if
    13.   { ... }
    14.   else
    15.   { ... }
    16. }
    17.  
    In such case, compiled code ignores checks of inner loops, If / Else If, as long outer loop case is not true.
     
  9. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    Applying my previous "else if" -> "else" + "if" translation (to the only case of "else if" in your example), that comes out to:
    Code (CSharp):
    1. if
    2. { ... }
    3. else
    4. {
    5.    if
    6.    {
    7.      if
    8.      { ... }
    9.      else
    10.      { ... }
    11.    }
    12.    else
    13.    {
    14.      if
    15.      { ... }
    16.      else
    17.      { ... }
    18.    }
    19. }
    20.  
    ...which I believe is exactly equivalent in meaning.

    More generally, if you have something like
    Code (CSharp):
    1. if (a) { F(); }
    2. else if (b) { G(); }
    3. else if (c) { H(); }
    4. else { K(); }
    that translates to:
    Code (CSharp):
    1. if (a)
    2. {
    3.    F();
    4. }
    5. else
    6. {
    7.    if (b)
    8.    {
    9.      G();
    10.    }
    11.    else
    12.    {
    13.       if (c)
    14.       {
    15.          H();
    16.       }
    17.       else
    18.       {
    19.          K();
    20.       }
    21.    }
    22. }
    G() could be a block of code that contains any combination of nested if and else; doesn't matter, because it only executes if !a && b
     
  10. WheresMommy

    WheresMommy

    Joined:
    Oct 4, 2012
    Posts:
    890
    Problem now is that you guys discuss about logics. Nothing to do with the first thread question I guess? ;) i think @Antistone wrote it quite easy to understand. If we get away of complex logics, the base performance is what was the question.
     
  11. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,778
    In fact, it is a lot to do with first question.
    But you only will be truly understand, if you start looking into compiled machine code. In such case, jump instructions.
    Otherwise, introducing potentially extra CPU cycles. But that is, if talking from the purly performance point of view.
     
  12. tcz8

    tcz8

    Joined:
    Aug 20, 2015
    Posts:
    504
    Thats what I also think. Some languages have an "elseif" keyword that probably saves that extra "if" call but in c# if there is anything to it its probably taken care of at compile time.
     
  13. mahdiii

    mahdiii

    Joined:
    Oct 30, 2014
    Posts:
    856
    For these problems and issues, pay attention to readability not performance!
    So you should write:
    Code (CSharp):
    1. if(){
    2. }
    3. else if(){
    4. }
    In addition, if you can convert it, the following is more readable.
    Code (CSharp):
    1. if(){
    2.    //...
    3.    return;
    4. }
    5. // else code
    6.  
     
    Last edited: Mar 20, 2019
    Overing and Antypodish like this.