Recently, I have been digging in my old source code. I ran across an if statement that was not optimized. In this instance, it was not a big deal. Two things that were similarly fast but one was more likely to fail than the other. The joys I get to experience when looking over my several years old code. While in this instance it was not a big deal, I have run into issue where failed short circuits of conditionals had a real impact on performance.
Many people hear about this in their computer science 101 class. It makes complete sense when they explain it to you. The issue with it is that it seems to be one of those things that programmers do but don’t think about very deep. As a result, we end up with failed short circuiting logic. The issue with this is you can lose performance. Now, I am not a performance nut but this is so simple to fix that it seems like a shame to not raise a bit of awareness to younger developers. We hear it. It makes sense and then it gets filed away for the test but not for real life. But I should probably start at the beginning.
What are short circuits?
A short circuit revolves around the action a conditional takes when it fails. If the first evaluation fails then the program stops evaluating the rest of the condition and continues down the else or else if path. If you use and/or statements in your if statements then you probably have played with it without thinking about.
I say probably because most languages have syntax that can force both conditions to be evaluated. Some languages default one way or an other. For instance VB.NET defaults more toward all conditions being processed. I think this is a left over from VB6 that was not changed when they went object oriented. The and/or both force both expressions to be evaluated. The AndAlso and OrElse force them to short circuit evaluate. Similarly, the && and || that is regularly taught are the short circuit operators for C# while & and | are the force all expressions to process.
Some languages support one but not the other. Personally, I have not consciously worked with a language that did that but in theory I have heard they do exist. You also have to watch which order things are in because some languages go right to left while others go left to right. Again, I have not consciously worked with one that I caught going right to left. If you know of any languages that go right to left, drop them down in the comments below.
One of the things that shocks me is how little anyone actually demonstrates this logic process in a way people can comprehend. I think this week, I am going to do a demo in both C# and VB.NET of the impact your order can have on performance.
How to evaluate using short circuits
When using short circuits, I tend toward putting the most expensive condition last. For instance, you have a big ugly SQL call that is slow to call. Put that at the end because you do not want to run that unless everything else passes. Save a bunch of sitting and spinning time and put it last.
Next for things that are roughly the same expense put the one that fails the most first so you can shave off those few nanoseconds of time by failing fast. It is a small change that can give some performance savings.
When not to use it.
If short circuits are so great, why not use them everywhere? If you have a function that is expected to run even if the evaluated condition is false then short circuiting could be really bad. Your code won’t have thing x prepared. Personally, I would attempt to refactor such a thing but sometimes it is not cost effective to do it. When you have to live with it, being able to force evaluation is a big luxury.
If you don’t like my take on it, try this article. It is one of the better explanations I have run into on the web.