With all the development I've been doing lately, both on Grind and my day J.O.B. projects, I've been thinking a lot about the code I've been writing. I make a nice little API that looks great but realize quickly it doesn't appear very efficient. I think, if I added this param I could cut out some lines of code inside this function. Or maybe, adding one more instance variable to this class would cut out this loop. I want to jump right in an optimize at the cost of complicating my pretty API.
I came across an article recently by Will Shiply discussing eliminating loops from Swift code (which is a fantastic article about Map/Filter), but there was a key statement that really hit home:
Follow this handy mnemonic, Johnny and/or Janey:
- Is the code as clear as possible? Yes? Good. Leave it alone.
- Did the code even show up in Instruments? No? LEAVE IT THE F ALONE.
It's true. Until I actively prove that code is causing a bottleneck there is absolutely no reason to optimize and make the code harder to understand. Clean code reduces so many more problems than adding complexity just because it appears slow.
Will expands a bit more:
As a sidebar about optimizing: don't optimize code until you've measured what's slow — just write good code as quickly as you can, so you have lots of time at the end to make the actual critical areas fast. But when first writing code we can't help but think about how slowly it'll run, so try to think of - how big the potential data set is normally (and in the most insane cases), - how often the particular code is run, and - how fast machines are. Then, if you think there will be a problem, feed your algorithm a bunch of data in a real-world situation and get an Instruments log.
It sounds so obvious. Of course you should do measure then optimize! But in reality, it's much harder to keep myself from premature optimization so I need to be diligent about preventing myself from falling into the trap.