I'm trying to figure out some best-practices for if-statements. When I need to switch on some equality, i.e. need an if-else construct, I usually write condition on "not-equal". The reason behind this is that usually, when a non-successful result comes, the number of instructions and also their complexity, are low. Is there any difference on the comparison process? Is there a difference in execution time between equal (==) and not equal (!=)?
Example (a rather simple one, but the general idea holds):
string myString = "weekend";
if(myString != "weekend")
{
Console.WriteLine("No fun...!");
}
else
{
//do a bunch of fun stuff with relatively high complexity
//can expand over many lines of code
}
Is there any difference in execution time if I change the order of the if-else statements?
string myString = "weekend";
if(myString == "weekend")
{
//do a bunch of fun stuff with relatively high complexity
//can expand over many lines of code
}
else
{
Console.WriteLine("No fun...!");
}
First off, the other answers which say (1) worry about something that matters, (2) write the code the way it looks best, and (3) if you're really concerned, measure it, are correct.
That all said, it is important to realize that the compiler is permitted to generate your code any way it feels like so long as the meaning is preserved, and compilers very frequently change the "sign" of a Boolean in an if
so that they can generate better code. Remember, when the compiler translates C# into IL, and the jitter translates IL into machine code, there will be no if
statement. There is just "generate a bool on the stack; now jump if the bool is true/false" in IL, or "put a bool in a register; now jump if the register is zero/nonzero" in machine code.
When you say:
if (A())
B();
C();
the compiler could generate the equivalent of these instructions:
call A()
if last result is false then goto SKIP
call B()
SKIP: call C()
Or it could just as easily generate:
call A()
if last result is true then goto CONSEQUENCE
goto SKIP
CONSEQUENCE: call B()
SKIP: call C()
Notice that the first version, which inverts the sign of the test, is one instruction shorter than the second version, and therefore is more likely to be generated by an optimizing compiler that is trying to keep your code short.
In that spirit, the compiler is allowed to choose to compare for equality instead of inequality, and invert the sign of the test, when doing so generates better code. And again similarly, the C# compiler will turn if (A() <= B())
into if (!(A() > B())
sometimes, and vice-versa, when doing so does not change the meaning of the program and when one version is shorter than the other.
My point is, changing from equality to inequality might not make any difference at all in the generated code because the compiler will automatically rewrite your code into the better version anyways. Trust the compiler to do its job, and worry about something else.
I would say you should write it the way that it's most readable. Such a micro-optimisation is unlikely to make any discernable difference to your code at all: you're talking at most a single "not" operation per comparison. If it were a significant difference then the compiler would likely optimise it away anyway, but really this is nothing to even think about.
On ordinary processors, the jump-if-equal and jump-if-not-equal instructions are very similar in terms of memory and speed. And that's assuming the compiler doesn't optimize away the difference in syntax.
Just thought I would have my say....
If this code is in it's own function already I would just perform the check and then return if I don't want to execute the rest of the code. Something like this:
void PointlessExample(){
string myString = "weekend";
if(myString != "weekend")
{
Console.WriteLine("No fun...!");
return;
}
//rest of the code
}
I would suggest moving your high complexity logic into a separate method, and therefore abstracting the logic, and simplifying your method.
string myString = "weekend";
if(myString == "weekend")
{
ComplexMethod();
}
else
{
Console.WriteLine("No fun...!");
}
That way it doesn't matter which way round you write your if statement.
In terms of performance, I don't think you'll find any significant differences between ==
and !=
.
Since there's no real difference in performance (and it would only really matter if you were in a very very tight loop), I'd strongly recommend not "standardizing" on == or !=, but instead just going with what makes sense in the situation.
I typically put the smaller case first, as otherwise you end up with a lot of hanging brackets at the end of your code.
e.g.
if (number != 1337)
{
Console.Writeline("Nope")
}
else
{
// Do lots of stuff
// Do lots of stuff
// Do lots of stuff
// Do lots of stuff
// Do lots of stuff
// Do lots of stuff
}
as opposed to
if (number == 1337)
{
// Do lots of stuff
// Do lots of stuff
// Do lots of stuff
// Do lots of stuff
// Do lots of stuff
// Do lots of stuff
// Do lots of stuff
}
else
{
Console.Writeline("Nope")
}
Some people prefer to put the actions first, and the edges cases later (saying that it's more like try {} catch {}) - so it's more a matter of style rather than best practice.
If do lots of stuff gets unwieldly, then you might want to consider wrapping it in a function, which means it doesn't matter what order you put the items
if (number == 1337)
{
DoLotsOfStuff();
}
else
{
Console.Writeline("Nope")
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With