Best practice for if

5

Which of the two code options performs better?

I'm going to display a very simple example, there's usually more code inside if .

A)

string mensagem = "OI";
if(exibirAdeus)
   mensagem = "Adeus";

B)

string mensagem = "";
if(exibirAdeus)
  mensagem = "Adeus";
else 
  mensagem = "OI";
    
asked by anonymous 03.02.2014 / 12:16

9 answers

6

The question is pertinent if the code block in if contains high computational complexity, written in the database or in files, etc.

The ideal between the two would be (A).

Why Performance (A) > = Performance (B)

Case 1 : Program execution always has exibirAdeus = true , Performance (A) = Performance (B) . Both (A) and (B), will always end up having the same flow:

Algorithm (A), Algorithm (B):

1. Atribui "" ou "Oi" para 'message'
2. Verifica 'exibirAdeus == true'
3. Atribui "Adeus" para 'message'

Case 2 : Program execution has 1 or more exibirAdeus = false , Performance (A) > Performance (B) . Because for these cases (B) will be more costly:

Algorithm (A):

1. Atribui "Oi" para 'message'
2. Verifica 'exibirAdeus == true': falso, não faz nada (message já é "Oi"). continua adiante.

Algorithm (B):

1. Atribui "" para 'message'
2. Verifica 'exibirAdeus == true': falso, precisa atribuir "Oi".
3. Atribui "Oi" para 'message'

Real World

However, if this block is small and of low complexity, this becomes extremely unnecessary.

The path you would follow is: How easy this code is for readability (readability & maintainability). I say this because there is a consensus * that in this case presented, you should be more concerned with putting the braces ({}) to demarcate the if-else blocks.

string mensagem = "OI";     // padrão: caso mais provável...
if (exibirAdeus) {
   mensagem = "Adeus";
}

or if the code starts to get more complicated as reminded by C. E. Gesser:

private bool Teste(){
    [..]
    string mensagem = initMensagem(condicao);
    [..]
}

private string initMensagem(bool condicao){
    if (condicao) {
      return "Adeus";
    }
    return "OI";
}

Another common case

string message = "";
if (condicao == 1){
   message = "blablbla";
}
else if (condicao == 2){
   message = "Lorem";
}
else if (condicao == 3){
   message = "Ipsum";
}
[..]
else {
   message = "Dolor";
}

It would be better written ** for performance, readability and maintainability:

string message = "";
switch (condicao) {
    case 1: 
       message = "blablbla";
       break;
    case 2: 
       message = "Lorem";
       break;
    case 3: 
       message = "Ipsum";
       break;
    [..]
    default: 
       message = "Dolor";
}

* link
link link

**
link
link

    
03.02.2014 / 12:49
7

I do not know if it is worthwhile to think about performance of such a short fragment and so fast execution. However we can make the following analysis:

In A) you initialize the variable and it will only be updated if the expression exibirAdeus is true. In B) you initialize the variable with a value that will never be used, this will have the cost of updating the variable independent of the value of exibirAdeus .

In this way I tell you that A) has better performance than B). But not for C #, but for the algorithm used.

    
03.02.2014 / 12:22
4

It's worth mentioning another option that escaped in the examples presented. Here using the ternary operator.

string mensagem = exibirAdeus ? "Adeus" : "OI";
    
03.02.2014 / 13:57
3

The best case is not A nor B . It is C :

string mensagem;
if(exibirAdeus)
  mensagem = "Adeus";
else 
  mensagem = "OI";

In A :

  • if DisplayAdeus == true, 2 objects are created ("OI" and "Goodbye")
  • if DisplayAdeus == false, 1 object was created ("Hi")

In B :

  • if DisplayAdeus == true, 2 objects are created ("" and "Goodbye")
  • if DisplayAdeus == false, 2 object is created ("" and "Hi")

In C :

  • if DisplayAdeus == true, 1 object was created ("Goodbye")
  • if DisplayAdeus == false, 1 object was created ("Hi")
03.02.2014 / 13:15
2

Considering your algorithm, for the processor the difference is almost insignificant (as almost everyone said) but it is obvious that if this if is within a loop for billions this mininum difference becomes more sensitive. I think it pays to think about the semantics of what you are writing and see if it makes more sense the first or the second, thus improving readability and understanding.

    
03.02.2014 / 12:38
2

As @Lizard correctly mentioned, performance depends on the likelihood of the condition and also on the optimization that the processor can do. However, I would add here the frequency of use of this routine.

See this very interesting question about processing speed in C . Modern processors are able to process multiple statements per cycle, so if the result of the Boolean expression is almost always the same, the processor has the ability to "predict" the result and optimize the processing as if if did not exist. / p>

I do not know how advanced the C # compiler is, but if even in a very high-level language like Ruby there was performance gain for processor-dependent optimizations, then C # would not be an exception.

In addition, if such a routine is used frequently, the initial String will already be loaded in cache and the cost of pointing a variable to it will be very small. In the second example, you are pointing to an empty String, which already requires variable assignment processing.

Finally, compared to the common performance bottlenecks, the difference in these stretches is practically nil. And this can be applied to most languages.

On the other hand, it is important to emphasize that if, in addition to the assignment, there is any kind of processing on the object, the scenario can change drastically. After so many affirmations that it "makes no difference," someone could opt for alternative A and add a conversion to upper case , for example.

    
03.02.2014 / 12:46
2

Between A and B , the most efficient would be A . But the very best would be a third one, a C :

string mensagem;
if(condicao)
  mensagem = "Adeus";
else
  mensagem = "OI";

But the efficiency of the algorithm revolves around the condition that it is used, of probability, so we consider the worst case. In A would have to change "OI" to "Adeus" after checking the condition, and in B would change the "" to "OI" or "Adeus" after checking the condition, whatever. Now the question should come up, why C if it looks so much like B , which is worse than A ? Because the assignment in B string mensagem = "" generates a more independent assignment of the case. In A the chance of a change in value is 50%, and in C the chance of a change does not exist, there will always be an assignment only. >

In fact the algorithm is very simple to consider its efficiency, but within a looping, or two, running thousands of times, with several possibilities, the relevance of something simple becomes important, making the execution time greater.

Consideration : The compiler will always check for else , it is not an overprocess, it is something inherent to the if conditional.

    
06.02.2014 / 13:05
1

The "A" alternative is very worthwhile if there is a greater chance that the message will be "OI". For example, it is known that there are more men than women in a given state.

When registering, it's worth doing:

char sexo = 'M';
if (mulher)
    sexo = 'F';

But do not worry about that sort of thing. The processor has a very large capacity and the difference in execution time is in milliseconds. For example, a teacher of mine said that:

int A = 10;

is 0.000014 faster than

int A = 2 * 5;

But tell me, will 0,000014 make a difference in your application? Of course not, but if you're still curious about the time difference, do the following. Declare a stopwatch, run method A, and then stop and display the time that elapsed. Then declare another stopwatch, run method B, and then display the time and still see the difference between the two. Stopwatch marks the time passed until your stop (such as a stopwatch). You can test (:

EDIT

EXAMPLE OF USE:

Stopwatch sw = new Stopwatch();
sw.Start();
//seu código aqui
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds.ToString());
    
03.02.2014 / 12:28
0

This will depend on case by case. If exibirAdeus is false in most cases, alternative A is more efficient, especially if the initialization of the variable is costly. Otherwise, it will make very little difference, it's more a matter of style.

    
03.02.2014 / 12:20