Posted tagged ‘guide’

The Art of Writing Good Conditionals

September 2, 2009

Based on my experience, many of the finer points of writing optimal conditional statements are not covered in most introductory computer science courses. For that reason, I thought I’d go ahead and write a post on the topic. There are other points that I will not be covering, but I’ll offer some advice on how to write great conditionals and I’ll show a few tricks on how to optimize your conditional statements. Keep in mind that conditional statement optimization is a form of micro-optimization and that performance gains from macro-optimization (ie. Good design, optimal data structures and algorithms) will be much greater. The code examples will be written in Java, for concreteness.

Common Mishaps

These are two simple examples of bad practices that should be avoided.

If you have a Boolean b, use it directly! Do not compare it with true or false:

If (b == true) {
//do something
}

Doing so adds a bit of overhead in your conditional (assuming the compiler doesn’t optimize it out). Instead, just write:

If (b) {
//do something
}

Use the following table to see the best use of the Boolean b in a conditional.

Expression Better Alternative
b == true / b != false b
b == false / b != true !b

Of course, in order to maintain code clarity, appropriate naming conventions are crucial. Using appropriate names means that one should be able to deduce the meaning of the expression simply by reading it:

if ( !empty && valueFound ) //Expression is easily understandable by reading it

Another bad practice is using the value of a Boolean indirectly:

if (someBooleanExpression) {
return true; //if true return true...
} else {
return false; //if false return false...
}

Again, just use it directly:

return someBooleanExpression; //use the value directly

Indirect usage of conditionals makes the code unnecessarily long, slightly slower and shows a lack of a true understanding of how Booleans work (or you weren’t paying attention :) , it happens)

Lastly, if you find that you’ve got a large if, else-if structure checking the value of an integral type, use a switch statement instead. Most importantly, switches increase code readability. Also, they are typically better optimized by the compiler and will be anywhere from much faster to roughly the same speed as a large if, else-if structure. The details of the optimization are the topic of a different discussion.

Short-Circuit Evaluation

Hopefully, if you’re reading this post, you are aware of this concept and can skip over this section. Short circuit evaluation occurs when a Boolean statement’s evaluation stops once the overall value of the Boolean is known.  Short circuit evaluation is typically enabled by short-circuit Boolean operators which differ from standard operators. This is the case with C++ and Java:

Standard operators: &, |

Short-circuit operators: &&, ||

This means that in the following two cases, otherExprs will not be evaluated:

if ( falseExpr && (otherExprs) ) //Always false regardless of value of otherExprs

if ( trueExpr || (otherExprs) ) // Always true regardless of value of otherExprs

If you know how to use these operators well, you can use them to write some pretty powerful conditional statements by deliberately short-circuiting in order to:

1. Avoid handling a null object erroneously:

if ( obj != null && obj.doSomething() )  //this ensures that contains is never called on a null object

2. Avoid expensive operations:

if ( value == lastValue || largeMatrix.contains(value) ) // if we can know that the large matrix contains the value without having to call the contains method, we do not need to make the call and can avoid the expensive operation, yes.. not the best example but you get the point

Regular Boolean operators should be avoided. However, in rare cases, they may prove useful: if a Boolean method has a side-effect that is desired regardless of the outcome of the expression then a regular operation may be useful.

if ( func1WithSideEffects() & func2WithSideEffects() ) //this ensures that both functions are always evaluated

Strategies for Conditionals

Finally, I thought I would outline two general strategies that can be used when writing conditional statements in a program. These aren’t hard and fast rules, so they should not be strictly adhered to in all situations. I’ll call the first strategy clarity.

The clarity strategy is an important strategy to follow, it deals with if blocks that handle numerous cases. It consists of placing the valid/good/expected case first, followed by the invalid/bad/exceptional cases.

if ( (x1 > 0 && x1 < 100) && (x2 > 100 && x2 < 200) ) {
//valid input first
} else {
//invalid input, can check what exactly makes it invalid here, or can use else-ifs instead of else
}

This makes code more readable and maintainable, and if the common case is the valid one, then performance is better as we do not need to check for all possible invalid scenarios, which in most cases is much larger than the set of valid ones.

This leads into the other strategy I’ll mention: speed. The speed strategy consists of handling the common case first (or fastest case first if its performance is such that it warrants being checked first despite occurring less often). Typically this strategy requires profiling to observe which ordering yields the best performance. Another important aspect is to effectively use the else block. The fact that the code has progressed to the else block means that all of the other expressions evaluated to false. By taking advantage of this fact, you can shift slowly evaluating expressions into the else clause, thus avoiding needing to evaluate them. In general, if you can use an else instead of an else-if based on the pre-conditions resulting from all the expressions evaluating to false, then do so. Use an assert statement instead if you want to ensure the conditions are indeed met.

Altogether, remember that macro-optimization is much more crucial, but by writing better conditionals you can really squeeze out those small performance gains, especially when tight looping is involved. Most importantly, better conditionals greatly improve code readability and maintainability.

–Ben

Advertisements

Opening a Dell Inspiron 6400/E1505

August 31, 2009

It’s been about a month since my last post, and a lot of things happened. I’ve been working on my work term report, finishing things up for the work term, playing Street Fighter 4… yeah. Now that my work term is over, one of the things I’ve been stalling on is changing my laptop fan.

I bought my Dell Inspiron 6400/E1505 just before going into university (Summer 2006). But once I got to university, the laptop was everywhere. I think this laptop is probably the most popular laptop of my generation, so I thought that this post might help someone with their computer problems.

Dell Inspiron 6400/E1505
Dell Inspiron 6400/E1505

I’ve been generally happy with my laptop though, had a few minor problems: a blue screen every now and then, and my CD drive doesn’t work at the moment. But from my experience, it seems like the fan is the first thing that breaks down after about 2 years of collecting dust. My fan died last summer in the middle of a LAN party. After, the fan was loud all the time; it was a little embarrassing in the library. But I never realized that the fan was the problem until I opened my computer, cleaned the dust, and checked the fan last January.

So I’ve opened my computer before. And that’s the main problem; the laptop’s annoying to open. I pried open some plastic, fooled around with some wires, and removed the palm rest, keyboard and monitor. Seems like a lot more work than needed. I don’t have much experience with technician work, but thanks to Dell’s service manual, it wasn’t that bad. You just need to be careful and follow instructions. It was good bonding time with my dad.

Innards of a Dell Inspiron 6400/E1505. Didn’t know the heat was transferred through those metal bars.
Innards of a Dell Inspiron 6400/E1505. Didn’t know the heat was transferred through those metal bars.

Replacing the fan was simple. Testing the fan turned out to be simple too. While opening the computer, I was sort of scared because I was too lazy to backup my stuff, but it turns out that the computer is still fully functional without the parts I took out. I used the palm rest to turn the computer on, and external monitor, keyboard and mouse for input/output. I used WarCraft III to trigger the fan. After, I cleaned the computer with some compressed air and put the computer back together.

Running my computer without the internal input/output components
Running my computer without the internal input/output components

Other than that, I ordered my fan off eBay. It’s the first thing I’ve ordered on eBay and I got it in about three weeks. Best of all, it was only four dollars American with shipping. Pretty good deal.

Next up, my CD drive. (You take out one screw and pull it out.)

The field of screws
The field of screws

Behind the text, your font

August 3, 2009

I’ve been looking for a good article on typography for a while. (But I haven’t really been trying.) Cheers to bumping in this introductory article on web fonts.