Feb 04 2015

Optimizing your code for clarity.

As a developer you will always encounter situations where there are multiple ways to accomplish the same task. Evaluating your options can be done by acting as if you are reviewing the resulting code.

The 4Cs are a useful tool for doing this and you’ll get better at each with pratice. Code clarity makes projects easier to work on for all levels of developers by being as close to self documenting as possible. If you can read a piece of code and understand immediately what it is doing, you’ll end up saving more time than if you wrote the most succinct code which can end up being slower to read. Clarity has a huge payoff but can be difficult to master. Fortunately it is easy to practice as it’s just as important that a single line be clear as an entire classes or method definition.

Let's use the following example:

We’re importing data for a project which contains ZIP codes stored as strings. Some records have a full nine digit ZIP code while others just have the more common five. For the application’s purposes, we do not need more information than the first five digits. Let’s look at a few ways to get the first five characters of a five or more character string:

zip_string[0..4]

zip_string[0...5]

zip_string[0, 5]

zip_string[/\d{5}/]

zip_string.to(4)

zip_string.first(5)

Ruby’s String

[]
method can take either a range (inclusive or exclusive), a starting index and a length, or a regexp and Rails adds the
to
and
first
methods to String.

All of the above are correct, complete, and concise but

zip_string.first(5)
ends up being the clearest.

This choice isn’t perfect and arriving at it takes a bit of thought. It’s a method added to String from Rails and not native Ruby. While the coupling is not concerning as it is incredibly unlikely the application will be separated from Rails, a developer could be confused as to why

first
doesn’t work in another non-Rails codebase or why they cannot find it in the Ruby docs.

Furthermore, I checked the source and

first
ends up calling
[]
with a few conditionals first. This results in a few more instructions being processed, but will never be a bottleneck until all of Rails is hyper optimized.

Reviewing the other options also places them below

first
. The regexp argument version of
[]
is likely to be the slowest and, unless you’re working in a shop with old perl veterans, regexps are not the easiest things to read. The rest have almost no perceivable speed difference and certainly not one that will ever be felt in your application. The range or index and length taking versions of
[]
end up being about equal in terms of speed and length with the index and length option being slightly clearer.

This simple example illustrates how small choices can shape your project and how to quickly evaluate them. It may seem minor but the clarity of your codebase will reflect the clarity of each and every line. Don’t get too wrapped up though. There are often two approaches that are equally as clear. It should take longer to read this post than to make that decision as clarity has a feel about it. In a future post I will demonstrate how some choices are equal and their differences may not necessarily matter. In these cases making a fast decision is for the best.

Do you think different? Is there an option I forgot or discounted too quickly? Let me know in the comments or on Twitter.

Aaron Rosenberg (@agrberg)

MojoTech

Share: