Should you sacrifice code readability with how efficient code is?
e.g. 3 lines of code into 1 line.
I read in Code Craft by Pete Goodliffe that readability is key.
Software Engineering Stack Exchange is a question and answer site for professionals, academics, and students working within the systems development life cycle. It only takes a minute to sign up.Sign up to join this community
"Fewer lines" isn't always the same thing as "more efficient". I assume you mean "Should a program be made shorter at the expense of readability".
Programs must be written for people to read, and only incidentally for machines to execute.
-Abelson & Sussman, Structure and Interpretation of Computer Programs
In general, I think it's more important that a program be easily understood than for it to be short. I should note though, that making a program shorter often also makes it more readable (there's the obvious threshold you get to when your code starts looking like line noise, but up to that point, expressing something more succinctly seems to make it clearer).
There are specific exceptions (like your personal shell scripts, or one-of data munging code) that no one will ever need to maintain, and only you will ever need to read. In that situation, it's probably ok to sacrifice some readability for expedience as long as you can still understand it.
Readability is a good thing to strive for. Most code written for typical line-of-business applications will be performant enough and focusing on readability is important. In more performance-demanding areas (such as video game programming or heavy computation), it may be important to forgo readability in favour of using a particular language feature that's horribly unreadable and yet incredibly performant.
For an example of the latter, see the Fast Inverse Square Root article on Wikipedia.
I generally think that it's better to make something readable first and worry about performance after, provided common sense precautions like not choosing an O(n^2) algorithm over O(n) are taken. Sacrificing readability for the sake of brevity alone is, in my mind, misguided.
The only time I'd sacrifice readability would be when the code was shown to be a performance bottleneck and a rewrite would fix that. In that case the intention of the code should be well documented so that if there is a bug it can be tracked down more easily.
That doesn't say that the rewrite has to be unreadable of course.
Should you sacrifice code readbility with how efficient code is?
In terms of code, it is always nice to be self documenting. But sometimes that can't happen. Sometimes you do need to optimise and sometimes that code isn't in itself very readable.
This is what comments were invented for. Use them. Even assembly has comments. If you've written a mass of code and there isn't a comment in sight, I'm worried. Comments do not affect run time performance, but a few notes on what's going on always helps.
There is, in my mind, absolutely no excuse not to have a few basic comments. Clearly
if ( x == 0 ) /* check if x is 0 */ is totally useless; you shouldn't add unnecessary noise to code, but something like this:
; this is a fast implementation of gcd ; in C, call as int gcd(int a, int b) ; args go in rdi, rsi, rcx, r8, r9 gcd: push rdp ; ...
Is quite helpful.
Should you sacrifice code readbility with how efficient code is?
If efficiency is your current goal (like in optimization phase) and you know - you have metrics, don't you? - that line(s) of code is the current bottleneck, then yes.
Otherwise, no : readability will allow you (or another one) to be able to change this code later to make it more efficient, as it is easier to understand.
No one wins Code Golf
e.g. 3 lines of code into 1 line
A particularly terrible idea.
Cost to play code golf -- very high.
Cost to maintain unreadable programs -- astronomical.
Value of this kind of minimized code -- zero. It still works, but doesn't work any "better".
Cost to chose the right algorithm and data structure -- moderate.
Cost to maintain the right algorithm and data structure -- low.
Value of the right algorithm and data structure -- high. Resource use is low.
Foolish ("micro-optimization") Efficiency
Cost to play around micro-optimizing -- high.
Cost to maintain unreadable, micro-optimized code -- very high.
Value of of micro-optimizing -- varies. When there is non-zero value here, the costs still outweigh it.
Depends upon if we are talking about efficiency in terms of how fast the code executes or efficiency in how fast the developer can write the code. If you are sacrificing the readability of the code in favor of being able to type code very fast then you will likely find yourself paying the time back down the road in terms of debugging.
However, if we are talking about sacrificing code readability in terms of how fast the code executes then it is likely an acceptable trade off as long as the code must preform in an efficient manner. Writing something that runs as fast as possible just because you can isn't nearly as good of a reason as because it is something like the fast inverse square root where performance is key. The trick is going to be between balancing the code and making sure that even though the source might be hard to read, the comments describing what it does explain what is going on.
Many tricks, which were supposed to make code faster, but tend to make the code less readble, are not necessary anymore, because either compilers got very clever (even cleverer than most developers) or machines got ridiculous fast.
I don't accept the "readability over performance" argument. Let me give you an answer with a different spin on it.
Some background: You know what makes me sick? When I double click on My Computer and I have to actually wait for it to populate. If that takes longer than 5 seconds, I get really frustrated. The stupid thing is, and don't just blame Microsoft for this, is that in some cases the reason for it taking so long is that a decision needs to be made on what icon to show! That's right. So here I am sitting, only interested in going to my C: drive, and I have to wait for the driver to access my CD-ROM and read the icon from there (assuming there is a CD in the drive).
OK. So just for a second imagine all the layers between me double clicking on My Computer and it actually talking via drivers to the CD-ROM. Now imagine every layer was...faster...
You see, behind all of this are 1000s of happy programmers because their code is "more readable". That's great. I'm happy for you. But from the user's perspective it just sucks (technical term). And so you sleep sound at night telling yourself that you did the right thing by making sure the code is more readable and yet slower. Even slightly slower than it can be. And so 1000s of developers do this, and we end up waiting for our PCs because of you. In my opinion you are not worthy. I am not saying your very first lines need to be the best.
Here is my approach: First, make it work, then make it faster. Always aim to write efficient code and if you have to sacrifice readability, supplement it with comments. I will not sacrifice efficiency so that some mediocre programmer can maintain it. I will however explain my code, but if that isn't enough, I am sorry, you are just plain incompetent to work here. Because here, we write code that's fast and readable, and although there is a balance, readable code can be explained whereas inefficiency is just unacceptable.
This question has often entered my mind when interviews are discussed in the office. Many years ago as a graduate, I was asked the question "Do you think code is self documenting?". Now, I was to answer this question as a programmer and as far as the interviewer was concerned, it was a black and white question, so there was no middle ground. The process should outlive the indivdual as people will more than lively come and go and you want to get new starts ready as soon as possible, and the easier the code is to read, the faster it is to comprehend what is going on.
I read a book a while back that was pretty good, called Domain Driven Development: Domain-driven Design: Tackling Complexity in the Heart of Software Admittedly, it's a bit of a dry read at the start, but the material is well presented. This shows a good approch that leads to systems that document themselves well. The language is the medium to communicate your solution, so the clearer the solution is expressed, the easier it is to adapt if performace does become a citical factor. That's my belief and it seems to have worked well for me.
Rarely would the ROI on making the code run faster at the expense of readability be worth it. Modern computers run so fast that I doubt there would be a scenario where you'd want this. If a computer is running the code, that code needs to be maintained.
To that end, I find readability very important. Of course, as stated numerous times, just because code is readable doesn't necessary mean it's slower.
A good example is a variable name:
$a?? This is out of context so you can't answer that but did you ever run into this in actual code? Now assume someone wrote
$file_handle -- now what is that? It's clear even out of context. The length of the variable name makes an insignificant difference to the computer.
I think that there is common sense to be had here.
Some applications might warrant a bit-shift short-cut that not all will understand but I think that at some-point there is diminished returns and finding a scenario is rare*.
* this does depend on industry and other such things. I'm looking at this from the perspective of business software developer (Business Information Systems).
To look at this from yet another perspective (but not to ramble), I work at a company that does SAAS. When a site goes down, we have to fix it really, really fast -- usually someone else is fixing another developer's code.
I'd much rather someone do something very inefficiently but readable than to make it fancy and "fast". Our web servers are cutting edge and a request doesn't need to be delivered in millionths of a second. We don't have load issues.
So, in practice I think you are more likely to hurt yourself or others... (I'd rather have my weekend back.)
For most every case, the answer is "Trust your compiler to do its job", and write code that is readable. This implies that the code is logically structured (i.e., no spaghetti) and self-documenting (i.e., sufficiently clear names of variables, functions, etc.). Supplement code that isn't self-documented with meaningful comments. Don't comment for the sake of commenting, i.e.,
x++; // Add one to x
Rather, comment for you, the reader, in 6 months or 12 months or some other sufficiently long time. Adopt a coding standard, and follow it.
Clean code is fast code. Clearly written, easy to maintain code tends to be faster because its an indicator that the programmer understood the task at hand, and refactored the code down to its core purpose.
Besides, modern compilers optimize instructions very effectively. How many lines of code you type to do something and what the compiler creates in terms of instructions are not necessarily related. Read up on compilers to understand why thats the case.
When I'm working on something performance based such as graphics, I'll occasionally sacrifice readability/maintainability when I'm doing things like image processing when I'm working on the deepest of nested algorithms where small optimizations can have a major effect. And even then I only do so after profiling to ensure the changes actually speed things up. I cant tell you how many times I've tried hand coded 'optimizations' only to find that it actually slowed down the app due to the way the compiler optimized the hand typed code.
Readability is an excuse for incompetent & lazy programmers (actually the same applies for "simplicity" when used as an argument to defend a crappy algorithm/design)!
For every given problem you should strive for the optimal solution! The fact that computers today are fast is not excuse to waste CPU cycles. The only constraint should be "time to deliver". Note that "optimal solution" here means the one YOU can come up with (we cannot all come up with the best solution; or have the skill/knowledge to implement them).
As someone else mentioned if there are "difficult to understand" aspects of a solution, that is what comments are for. The order "correct, readable, fast" (or something like that), which someone else mentioned is just waste of time.
I have a really hard time to believe that there are programmers out there, which when presented with a problem they think in the lines "...this must be done like this but I will make that way which is less efficient but more readable/maintainable and other such crap...". The fallacy of this is, that the next developer (seeing the inefficiencies) will most probably modify the code and the next will do the same and so on... The end result is that after a few versions the code will become what the original developer should have written in the 1st place. The only excuse for the original developer is a. he/she did not think of it (fair enough) and (as mentioned before) b. time & resource constraints.
if decreasing readability helps code performance/optimization (as in swfobject and other js libraries) it's a reason just to keep writing well-formated and clearly readable code and convert it to unreadable/optimized as a part of "compilation"/release process.