Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Benefits of using short-circuit evaluation

boolean a = false, b = true;
if ( a && b ) { ... };

In most languages, b will not get evaluated because a is false so a && b cannot be true. My question is, wouldn't short circuiting be slower in terms of architecture? In a pipeline, do you just stall while waiting to get the result of a to determine if b should be evaluated or not? Would it be better to do nested ifs instead? Does that even help?

Also, does anyone know what short-circuit evaluation is typically called? This question arose after I found out that my programming friend had never heard of short-circuit evaluation and stated that it is not common, nor found in many languages, and is inefficient in pipeline. I am not certain about the last one, so asking you folks!

Okay, I think a different example to perhaps explain where my friend might be coming from. He believes that since evaluating a statement like the following in parallel:

(a) if ( ( a != null ) && ( a.equals(b) ) ) { ... }

will crash the system, an architecture that doesn't have short-circuiting (and thereby not allowing statements like the above) would be faster in processing statements like these:

(b) if ( ( a == 4 ) && ( b == 5 ) )

since if it couldn't do (a) in parallel, it can't do (b) in parallel. In this case, a language that allows short-circuiting is slower than one that does not.

I don't know if that's true or not.

Thanks

like image 236
Swati Avatar asked Sep 18 '08 01:09

Swati


2 Answers

Short-circuiting boolean expressions are exactly equivalent to some set of nested ifs, so are as efficient as that would be.

If b doesn't have side-effects, it can still be executed in parallel with a (for any value of "in parallel", including pipelining).

If b has side effects which the CPU architecture can't cancel when branch prediction fails then yes, this might require delays which wouldn't be there if both sides were always evaluated. So it's something to look at if you do ever find that short-circuiting operators are creating a performance bottleneck in your code, but not worth worrying about otherwise.

But short-circuiting is used for control flow as much as to save unnecessary work. It's common among languages I've used, for example the Perl idiom:

open($filename) or die("couldn't open file");

the shell idiom:

do_something || echo "that failed"

or the C/C++/Java/etc idiom:

if ((obj != 0) && (obj->ready)) { do_something; } // not -> in Java of course.

In all these cases you need short-circuiting, so that the RHS is only evaluated if the LHS dictates that it should be. In such cases there's no point comparing performance with alternative code that's wrong!

like image 176
Steve Jessop Avatar answered Oct 19 '22 10:10

Steve Jessop


Short circuit evaluation is translated into branches in assembly language in the same way if statements are (branches are basically a goto), which means it is not going to be any slower than if statements.

Branches don't typically stall the pipeline, but the processor will guess whether the branch is taken or not, and if the processor is wrong it will have to flush everything that has happened since it made the wrong guess from the pipeline.

Short circuit evaluation is also the most common name for it, and is found in most languages in some form or another.

like image 12
sirwart Avatar answered Oct 19 '22 09:10

sirwart