Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which is the more efficient syntax for NAND (not both true) in C#?

The NAND logic gate for two conditions (A and B) is true as long as either condition is true, or none of the conditions is true; and it is false if both conditions are true.

F NAND F = T
F NAND T = T
T NAND F = T
T NAND T = F

In C# I can write this in at least two ways:

!(A && B)

or

(!A || !B)

Which is more efficient?

It seems to me that if(A) then B is always tested and if(!A) then B is never tested.

But then the first condition must invert the result....

like image 832
Matthew Avatar asked Aug 03 '13 20:08

Matthew


1 Answers

It is not quite as simple. The C# language doesn't model a NAND gate at all with the && operator. That operator has short-circuiting behavior, very convenient in a C# program. And common behavior for the curly-brace languages, an expression like this doesn't crash your code:

arr[] = somefunction();
int ix = foo;
if (ix < arr.Length && arr[ix] == 42) {
    EmailBookRecommendation();
}

But that's a very inefficient version of the expression, this one is way more performant:

if (ix < arr.Length & arr [ix] == 42) 

Which is a perfectly legal expression, the & operator works just fine with boolean operands. But unfortunately this one crashes your code. It evaluates the array indexing expression and that goes Kaboom! with IndexOutOfRangeException.

That's not ever a problem with a NAND gate, it doesn't crash when the first input is F :) There are many possible C# expressions where that's not a problem. You really should favor the & operator for those. It makes a huge difference. So always write something like this:

if (ix >= 1 & ix <= 42) 

Which of course can never fail. To understand why the && operator is so much more inefficient than the & operator, you have to understand branch prediction. That's covered very well in this answer.

like image 60
Hans Passant Avatar answered Oct 25 '22 21:10

Hans Passant