As a software engineer, it is unbelievably easy to get lost in the world of ‘least memory’, ‘most elegant solution’, or my all-time favorite, ‘fewest clock-cycles’. All of these ideas simply mean to maximize the performance of the code. This idea permeates the world of software development and eventually leads to the conclusion that the best engineer is the one that builds the fastest, most elegant, least resource intensive solution. The idea is drilled into our heads, starting in the first days of programming 101. So, it is no surprise that by the time our bright young developers enter the professional work force, it has morphed into almost a religion.
Simply stated, developer’s always want to reduce the amount of resources they are using: use less processing time, less energy, less memory, and even fewer lines of code. Less is better! Least is best! While there are certainly cases where this in fact the most important consideration, I’m going to offer a different perspective.
Which Resource Matters Most?
The problem of focusing on the number of resources our code uses, is that we usually neglect the most important resource of all: the number of engineering hours it takes to do something. Neglect is a strong word and means exactly what it implies: we neglect how valuable our own time is as engineers. We are ever so eager to consider how much CPU time our code takes, but ironically, we don’t like to think about the most important time of all – our own. In reality, engineering time is the most limited resource we have. Engineers are expensive and honestly, we never have enough of them.
Now, this might not be so bad, but there is another problem that complicates things. In general, engineers have trouble predicting how long it takes to implement something. Over time, this has become somethinf of a cliché. Take the engineer’s estimate and double it (2x), or triple it (3x), or even multiply it times ten (10x). Engineers will argue that they tend to estimate correctly, but there are usually complicating factors. And, in fact, they may be right. The problem is not so much that we can’t estimate time. The real problem is in terminology.
When engineers estimate time, they try to think of what it takes to get ‘er done, but they rarely think of what it takes to get ‘er ‘done-done.’ ‘Done-done’ is an expression that evolved over time and points out the problem of terminology. Just one ‘Done’ can mean all kinds of things, depending on exactly what question you ask. Is the basic algorithm done? It the demo done? Is the integration with other members of the team done? Are all the boundary cases done and is the check in done?
Over time, I began to ask if something was ‘done-done.’ This is a different question. It asks if they are completely and 100% done in every possible way: the code compiles, it runs, it does what it’s supposed to, it is tested and integrated, and it is even checked in. If you say ‘yes’, then you better be completely finished and ready to move onto something else. When we estimate tasks, we usually think about how long it takes to be ‘done’, but we rarely factor in how long it takes to be ‘done-done’ – and that takes much longer.
So, with those 2 problems in mind, we can now go back to where we started – the idea of making the code as awesome as it can be. It’s almost in our blood to want our code to be stylish, efficient, and use the latest uber-efficient algorithm. That’s part of the fun, it makes us proud of our work, and sometimes it even helps us feel smart! But, now consider what happens when you mix in the idea that we don’t think of our time as the most important resource and the idea that we rarely think in terms of getting things, ‘done-done.’ Now, we have the ingredients for disaster. And, that is the source of the clichés and the 2x, 3x, and 10x multipliers.
This is exactly the case that Jonathan Blow makes in his speech, ‘How to Program Independent Games .‘ Jonathan Blow is the award winning developer of Braid, founder of a successful independent game company, and generally, one of the smartest engineers you are ever likely to meet. His advice is that being the best engineer is not about using the least number of computer resources, it is about using the least number of developer resources. He explains that it is more important to get it done quickly, simply, and truly finished (aka ‘done-done’). His talk is deep on many levels and offers a perspective we rarely consider. As he explains, being a good engineer is not about being smart – it is much harder than that. Being a good engineer is about truly understanding the value of our own time. And that is not ‘smarts.’ That is what is known as wisdom.