views:

69

answers:

6

If I have a Boolean expression to check

(A && B)

If A is found to be false will the language bother to check B? Does this vary from language to language?

The reason I ask is that I'm wondering if it's the case that B is checked even if A is false then wouldn't

if (A) {
  if(B) {

  } else {
     // code x
  }
} else {
  // code x
}

be marginally quicker than

if (A && B) {

} else {
   // code x
}
+4  A: 

This depends on the language. Most languages will implement A && B as a short-circuit operator, meaning that if A evaluates to false, B will never be evaluated. There's a detailed list on Wikipedia.

Victor Nicollet
+1  A: 

Many languages (including almost all curly-brace languages, like C/C++/Java/C#) offer short-circuit boolean evaluation. In those languages, if A is false then B won't be evaluated. You'll need to see (or ask) whether this is true for your specific language, or whether there's a way to do it (VB has AndAlso, for example).

If you find your language doesn't support it, you'll also need to consider whether the cost of evaluating B is worth having to maintain two identical pieces of code -- and the potential doubling in cache footprint (not to mention all the extra branching) that'd come from doing that duplication every time.

cHao
+1  A: 

Almost every language implements something called short-circuit evaluation, which means that yes, (A && B) will not evaluate B if A is false. This also takes effect if you write:

if (A || B) {
    ...
}

and A is true. This is worth remembering if B may take a long time to load, but generally it's not something to worry about.

As a bit of history, in my mind this is a bit of a sore part of LISP because code like this:

(if (and (= x 5) (my-expensive-query y)) "Yes" "No")

is not made of functions, but rather so-called "special forms" (that is, "and" could not be defun'd here).

Mike Axiak
+1  A: 

This would depend 100% on how the language compiles said code. Anything is possible :)

Is there a specific language you're wondering about?

PersonalHomePage
+1  A: 

In short, no. A double branch involves various forms of branch prediction. If A and B are simple to evaluate, it may be faster to do if (A && B) in a non-short-circuit way than if (A) if (B). In addition, you've duplicated code in the second form. This is virtually always (exception to every rule .. I guess) bad and far worse than any gain.

Secondly, this is the kind of micro-optimization that you give to the language interpreter, JIT or compiler.

DeadMG
I was thinking of instances where B is a really complex condition (in the app I'm working on at the moment it's about 5 or 6 inequalities with the || operator between them, and it gets called lots of times on page load)... but as javascript uses short-circuits it looks like it won't be a problem
wheresrhys
David Thornley
If you're in C, why not just use `if (type* p = some_init()) { p->a; }`
DeadMG
David Thornley
@David Thornley: The idea is obviously that you could place any expression in the if block, and that p is only used if valid in a much cleaner and easier way.
DeadMG
@DeadMG: It doesn't matter how much cleaner and easier it is if it doesn't work. To repeat, in C, statements are not expressions. Meditate on 'if (if (type* p = some_init()) { p->a; })...` until it all becomes clear.
David Thornley
Perhaps, you should mediate on the simple idea of using a char temporary variable. The idea of using a small arithmetic temporary is non-optimal, but it's far MORE optimal than micro-optimizing and potentially leaving NULL pointers around.
DeadMG
A: 

As others have said, it depends on the language and/or compiler. For me, I don't care how fast or slow it might be to short-circuit or not, the need to duplicate code is a deal-killer.

If A and B are actually calls that have side-effects (i.e. they do more than simply return a value suitable for comparison), then I would argue that those calls should be made into variable assignments that are then used in your comparison. It doesn't matter whether or not you always require those side-effects or only require them conditionally, the code will be more readable if you don't depend on whether or not short-circuit exists.

That last bit about readability is based on my feeling that reducing the need to refer to external documentation improves readability. Reading a book with a bunch of new words that require dictionary look-ups is much more challenging than reading that same book when you already have the necessary vocabulary. In this case, short-circuit is invisible, so anybody that needs to look it up won't even know that they need to look it up.

jadero
I'll use C for an example. If A is an expression that assigns a pointer value to `p`, which could be valid or the null pointer, and B is an expression that uses `p` and has other side effects, then you cannot simply evaluate A and B and then use their truth values. Nor is short-circuiting an obscure part of the language, so there's no need to avoid it for fear of confusing somebody.
David Thornley
@David Thornley: In your example, you could easily check to see if A's return value is valid before proceeding with B. My concern with conditional evaluation via short-circuiting can be contrasted with the concern many have with the conditional operator (?:). At least it has an explicit syntax, unlike short-circuiting. To someone coming from a language that offers no conditional operator, the need to check documentation is obvious. Short-circuiting provides no such indication. FWIW, I'm probably biased because I came from a language that had neither, and only short-circuiting tripped me up.
jadero
@jadero: I stand by my earlier position: short-circuit operators are part of C, and are commonly used as such. Any competent C programmer will use it properly, and any programmer competent in a number of other languages will expect short-circuit behavior. I don't agree with suggesting that it not be used because a real novice might be confused.
David Thornley
@David Thornley: You've convinced me. As it happens, that is pretty much the same argument that I've used when people have told me that I should avoid the use of the conditional operator :) Thanks.
jadero