Data Centers

Why clean code is more important than efficient code

Efficiency can be important when writing code, but it should usually take a back seat to writing clear code. Chad Perrin explains why.

There was a time, long ago, when the most important thing you could do with your code was to make it more efficient -- in terms of how much functionality you can pack into every kilobyte of storage, how tightly it compiles, how little RAM it uses, how much you can communicate in every network packet sent, and so on. In those days, many computers did not even have random access persistent storage, you could only run one program at a time, and RAM was measured in bytes rather than gigabytes. Those days are long gone.

There are still reasons to pay attention to efficiency when writing code. A poorly written Fibonacci sequence generator could take hours to produce the first 100 numbers in the series. An operating system that requires 20 gigabytes of storage just to be minimally useful does not serve very well for use on embedded devices. A browser that suffers memory fragmentation problems can actually consume all the RAM and swap space on your system after a couple days of very heavy use.

As computing resources continue to grow, efficiency falls further behind another concern when writing code, though. That concern is the cleanness of the code itself. Mostly, this boils down to readability and comprehensibility. Programmers need to be able to read and comprehend your code -- programmers that will come along after you have moved on and even when you come back to your own code in six months.

Without readability and comprehensibility, you cannot easily reuse your code. You will be forced to reinvent the wheel many times over if you decide it is easier to write from scratch than use what you have already written when that would otherwise serve perfectly well. When writing open source software, the same problem applies to other people. Even worse when writing open source software, if your code is unreadable or -- once read -- incomprehensible, nobody else will bother looking at the code very much; you will not get any feedback on it other than (perhaps) complaints about that, you will not get code contributions, and ultimately your "open source" will be so opaque as to be effectively closed. It may be easier for others to just rewrite the needed functionality and put your project "out of business". This is happening to GNU Screen right now.

The problem is just as bad in closed source software development. Bugs are easier to fix when you can understand your own code. Features are easier to add, too.

When efficiency matters, it is easier to see where the efficiency bottlenecks reside if your code is clear.

I wrote a program that makes use of a plain text YAML flat file database. As you may recall from an earlier article, YAML is a popular format for simple data storage with Ruby (and other languages). When data structures start getting complex and large, YAML is not the most efficient tool in the toolbox. It offers some advantages, however; its format is very clearly human-readable, it is widely supported, it does not require complex software systems like typical relational database management systems to access data, it translates directly into common data structures, and interacting with it is easy with popular YAML libraries.

The data stored in the YAML file used by this program is getting more complex, and there is more of the data over time. I am starting to look at the need to use a more robust data format, such as SQL. Basically the only question about this that lies before me right now is: Should I use SQLite or PostgreSQL? Before making that data migration, though, I need to add more functionality to my program, because I have been making edits directly to the YAML data file at times where it was easier to do that than to wrap simple methods around alterations in functionality. Yes, I need to rewrite part of the program to deal with a data format change, soon. No, I do not consider this a poor choice of data format in the early stages of development.

I chose YAML in part because I needed human readability in a structured format that was easy to manipulate with code. This was of critical importance early on, and development would not have proceeded with nearly as much alacrity in early stages if I had not made that decision -- if I had chosen to use PostgreSQL from day one. In fact, the whole project might have just stalled and withered away. Even if that was not the case, the flexibility afforded by this data format to how I dealt with my data saved me far more time than I will have to spend on the migration of data formats.

In working on that same project, I wrote code that correlated a short list in one record with a long list of values that resided in another record, summed values that matched between the two lists, and presented the result. This was written as an atomic operation whose code resided entirely within a single method, including:

  • opening the YAML file
  • reading the data into a data structure
  • closing the file
  • correlating list items and producing a sum of values
  • returning the sum, and
  • letting the data structure go out of scope.

It was all very clear and clean code. Unfortunately, it turned out to be horrifically inefficient, though I did not notice this fact at first. It was only later when I decided I needed to be able to perform this operation hundreds of times and produce tabular output to show a visible matrix of results that the failures of that approach became obvious. The problem was loading an increasingly large YAML file's data into a large, complex data structure every single time one of these values needed to be calculated. For efficiency's sake, this should obviously have been done outside the method.

As fellow TechRepublic contributor Sterling Camden can tell you, I was pretty hard on myself for that lapse at the time. I was simply flabbergasted I had done something like that, building such a huge resource sink into such a simple little method. There are times that efficiency matters, and this was definitely one of them. I had managed to completely miss the importance of efficiency in this case, and made what appeared to be a very amateurish mistake. This was not 10 years ago; I could not blame this on a significantly more naive me. It was closer to 10 weeks ago.

Now that I have had more time to think about it, I realize that I did not really do anything wrong. By wrapping up the entire operation in a single method, I had satisfied the needs of the functionality at hand. I did so in a way that made it incredibly clear where the method was getting its data, and that the data had not been altered in any way by the program before it was used as the basis for this operation. It was about as clear as it could possibly be under the circumstances, which aided in the task of constructing a series of algorithmic steps that would complete the needed operation as simply and straightforwardly as possible. It also made it much easier to test the code for unexpected edge cases.

When I first wrote the method, my focus was entirely on the clarity of my code, and as a result I had useful functionality that served me well -- until I needed more. Because the code was so clear, and I had a better idea by then of the sort of uses to which I would want to put this functionality, I was able to accomplish the needed rewrites quickly, easily, and most importantly clearly when the time came to make changes to support the more resource-intensive series of operations I then needed. If my focus had been on efficiency to satisfy needs I did not yet know I had, the structure of the program as a whole might have been significantly more complex and difficult to sort out when changes needed to be made. Ultimately, the highly inefficient but very clear way I wrote that method early on offered the readability, comprehensibility, and structural simplicity to make an important refactoring much easier to undertake.

As long as your code meets the basic requirements for efficiency needed to suit your needs for the immediate future, clarity trumps efficiency. As Donald Knuth put it, "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil." There are those who disagree with this idea. Developer Joe Duffy said:

Mostly this quip is used to defend sloppy decision-making, or to justify the indefinite deferral of decision-making. In other words, laziness.

His attack on the "premature optimization" culture is well written and in-depth. His argument basically boils down to this statement from near the end of the page:

I'm not saying Knuth didn't have a good point. He did. But the "premature optimization is the root of all evil" pop-culture and witty statement is not a license to ignore performance altogether. It's not justification to be sloppy about writing code. Proactive attention to performance is priceless, especially for certain kinds of product- and systems-level software.

Based on the above description of how I ended up making certain choices about how to write my YAML-using program, he would probably call me lazy. His certainty of my laziness would probably only be reinforced if he knew that one of the reasons I chose YAML is the simple fact that I find it easy to use, and had never written Ruby code that used SQLite before.

It was not lazy in the sense he means, though. It was carefully approached coding, with a focus on making things as clear as I could. I was not thinking about performance, about the efficiency of what I wrote, at all; I simply did not want to think about it at the time. What I did want to think about was, at the time, much more important -- and is often one of the most difficult things to achieve when writing code.

I wanted it to be simple, elegant, readable, and fully comprehensible. That takes work.

When I discovered my efficiency problem, I felt pretty stupid for a while. After having thought about it, though, I have come to realize that if I had that choice to make over again, with the same knowledge of what I might need in the future -- very little -- but more awareness of the fact I was writing horribly inefficient code, I think I would have made the same decision. I hope I would because, at the time, efficiency did not matter; when it would come to matter in the future, the clarity of the code I wrote is what allowed me to change the code to suit the needs that arose as easily as I did.

Just remember, the admonition that premature optimization is the root of all evil does not give you license to write bad code. It is an encouragement to consider other factors than efficiency whenever you can get away with it, because optimization can be added, but as our code gets more complex clarity only suffers. More to the point, clarity helps you figure out how to make your code more efficient later, but efficiency never really helps you figure out how to make it clearer.

Besides . . . one of the benefits of clear code is that making your code clearer usually involves making it shorter too, contributing to the efficiency of source code storage.

About

Chad Perrin is an IT consultant, developer, and freelance professional writer. He holds both Microsoft and CompTIA certifications and is a graduate of two IT industry trade schools.

144 comments
Captn Obvious
Captn Obvious

Those who say efficiency is not important have clearly no idea what is it like to write numerical software for science or engineering. No real engineer would discard even a 10% improvement on a design without a very good reason to do so. And many programmers still manage to add enough 10% losses in a code to achieve resource utilizations of less than 1%.

This is why computers are thousands to millions of times faster now than the first PCs and yet all the poorly-written bloated software around still manages somehow to need even more resources.

The very idea that we've had 64-bit, multicore chips for more than a decade and the majority of commercial software is still 32-bit single-threaded is a reason good enough to fire all software developers involved.

CodingUncut
CodingUncut

Hi,


I think there is a clear path from clean code to efficient code, but the reverse is mostly not true.


If by clean code we mean "obviously no defects vs. no obvious defects" then we are talking about code that is either simple (small units, well-named, right level of granularity, good abstractions) or we are talking a good match to the problem domain (good abstractions, clearly defined concepts, etc.).

In "efficient code" we are often willing/forced to sacrifice many of the above, and to sacrifice meaning and clarity on the altar of the compiler ;)

In "efficient code" we tend to write for the compiler rather than for human readers, and this takes its toll on maintainability and evaluating correctness.


Johannes

dougswamp
dougswamp

Neither matter. I wrote the greatest search / multimedia player (in one huge program) and the techies hated the code and wouldn't try it. This program has evolved since 1999 and I can randomly pick a video along with a random start point and play for a few seconds then the next... I can select a start point in a video and play it for a few seconds then switch to slow motion for a preset time then switch back to full speed. Without editing using timeline playback. It does this and a lot more. Waaay more. Nobody Shares Knowledge Better than this. Google that. I'm calling each and everyone of you TECHIES out. Sorry for flaming you. But I have been banned here for years and keep getting your dumb old emails. Quit sending me stuff and I'll leave you alone. I have heard all the stuff about efficiency and readability and say Phooie. I even added line numbers back into this program. Knowing it would infuriate the Know-It-Alls and the too goodies.

charlie204
charlie204

One of the main reasons why optimizing early is a mistake is that you will wind up spending your time optimizing the wrong code. It is far better to write clear code which can be understood by the maintenance programmer. Remember, you may have to be maintaining your own code some day! Writing code like if (c == 4) may be no different than this: if (4 == c). However, if you accidentally leave out one equals sign, and the other will generate a compiler error (much preferred). Style is an understated but important part of any programming task, and using good style is probably as important as properly commenting your code. If the code is 'tricky', then it is by definition not efficient. That is not to mean that it will not run rapidly, it may. However the time spent debugging someone else's 'cutsey' code is not worth the expense involved. Spagetti code was the operative COBOL way prior to structured code. When structured code was first brought into existence, the benefits of having 'provable' logic certainly outweighed any so-called efficiencies which might have been available in spagetti code. Mixing performs with perform thru an exit paragraph was a huge source of logic errors. Whatever the language, consistency in style is important. First, make the code work corrrectly. Next, see how it might be improved to work faster without adding complexity (which makes maintenance of that code more expensive). Unless you are only programming at home for yourself, you need to consider the costs involved.

wilback
wilback

Repeated posting, sorry... I wish there was a way to delete my own posts.

wilback
wilback

Sorry for all the repeats, nothing visible was happening when I clicked "Save" so I clicked it several times. Arrrgh....

wilback
wilback

Repeated posting, sorry... I wish there was a way to delete my own posts.

wilback
wilback

Repeated posting, sorry... I wish there was a way to delete my own posts.

wilback
wilback

Repeated posting, sorry... I wish there was a way to delete my own posts.

wilback
wilback

Repeated posting, sorry... I wish there was a way to delete my own posts.

wilback
wilback

Repeated posting, sorry... I wish there was a way to delete my own posts.

wilback
wilback

While there is a general rule here about efficiency vs. cleanliness, it's also an example of how most programmers don't understand just how much repeated disk access costs them. If this was understood by Mr. Perrin originally, he would have realized the potential problem when he first wrote the code and at least checked its impact as the database became larger. This is a classic case of efficiency versus cleanliness. Many OSes such as Linux use APIs for I/O that deliberately hide the underlying peripheral device. There's good reason for this abstraction, but at some point the ugliness of the real world kicks in. I once worked on a ftp server written by a Linux guru that treated disk accesses just like memory accesses. He implicitly assumed that the server was processor and memory bound instead of disk bound, and repeatedly reread the database from the disk. When I rewrote the code to minimize disk accesses, it's performance improved by 40%. I don't think my code was any more complex than the original; it just had a better understanding of which resources were the most limiting.

AhmedAba
AhmedAba

Excellent post Chad, I think what you meant is Scalable not Efficient code, because efficiency is not a compromise issue. My code MUST be efficient otherwise i will not publish it. The scalability is where your code work when ever there is a more need for speed, users, storage, ... So I think you should have changed efficiency to scalability. Efficiency means correct code, correct output, not speed of respond or storage or new needs. Clean means well organized code as you said. So I think you should have explained Clean and Efficiency before diving into this intersting post. Thanks, Ahmed.

ammar_zaatreh
ammar_zaatreh

In effect your argument boils down to this: Make your code clean and simple so you can make it efficient when you need it to be. Clean comprehensible code makes all kinds of fixes and modifications easier, increasing efficiency included, where highly efficient yet sophisticated code serves only it's efficiency. In that case, we can make this logic work, but we'll always need better and better compilers, since we already made our code easy to understand, compilers that can actually understand it as we do is the next logical step. I used to write my code clean and readable to the utmost extent, then go through it little by little turning >If the Input is 1, make the Output 2. >If the Input is 2, make the Output 1. into >Output = 3 - Input as Englebert puts it. Needless to say, that only works if the code was mine alone and written as a final draft, not to be improved upon or changed much in the future, which is of course, almost always not the case. That's why I want a compiler that can do the above fix on it's own even before it start working on binary efficiency.

CodeCurmudgeon
CodeCurmudgeon

I've learned from long experience (learning since '73 full time programming since '80) that If I come up with a tightly optimized way to do something, revised requirements will result in my having to completely rewrite that code, 'cause the tightly optimized code can't adapt to allow the needed extension.

GrizzledGeezer
GrizzledGeezer

Some programmers might be geniuses, but few of them display any real intelligence. Once upon a time, when I was programmer, I started my coding by WRITING THE CODE COMMENTS. This had several advantages, one of which was removing the need to keep in mind what I had to do as I coded. It also made it easier to spot errors or "missing" code. And, of course, it guaranteed that the code was commented. Anyone who thinks there's such a thing as "self-documenting" code is delusional. What is obvious when you write it can be "more opaque than a solid body" a week later. Several years ago I spend\t several months at Microsoft reverse-documenting the Account Manager software. Apparently, it was just Too Much Trouble to properly document it whiloe it was being written.

serbdeep.singh.nezar
serbdeep.singh.nezar

The days has gone where you had writing the code from scratch. now a days the trend is to use/ buy tool/open source components to customize/enhance further. i would say, for this writing clean code is important now a days. other factor is high attrition rate :) , New member should understand whatever you written so that they can remember you +vely.

apotheon
apotheon

Who, exactly, is "missing the point on optimization"? You basically just restated part of the message of the article, so you must be disagreeing with some comment in discussion -- but the manner in which you posted your comment does not indicate whose comments you dispute.

AnsuGisalas
AnsuGisalas

Don't worry about it, has to do with the continuing updates to the board code.

apotheon
apotheon

> If this was understood by Mr. Perrin originally, he would have realized the potential problem when he first wrote the code and at least checked its impact as the database became larger. I don't think you read the article very closely. It was understood; it just wasn't taken into account. The fact of the matter is that (as you'd understand if you read more carefully and thought about it a little more) the size of the database is not the limiting factor in the development of the method used to generate values from the database. The limiting factor was the number of times the database was accessed, pretty much regardless of size.

Tony Hopkinson
Tony Hopkinson

would be to delegate retrieval and storage to some subsytem that would be optimised for how it was being implemented physically. Re-reading the entire database has nothing to do with clean, it's an optimisation, in this case a poor one... Bottlenecks in processing are very easy to see with 20/20 hindsight, while you are deep in the code, your only sensible defense is to make it as clean as you can then optimise if you have to which is what many of us have said. If matey boy had wrote a complete tip or optimised for soemthing wildly different, you would have been bollocksed...

auogoke
auogoke

I'd say that...code that does not scale when it should is not really efficient.

Tony Hopkinson
Tony Hopkinson

If you don't want to keep recalculating or even retrieving a value you cache it. So you've made your code faster, but increased the amount of required resource. Keep going down that route, and eventually you have a piece of code that takes a long time to throw an out of memory exception. Or thrashes the page file, or uses up so much of your machine, you can't do anything else. Optimisation might have been a better choice of word, scalability, naff all to do with it.

apotheon
apotheon

You have strange definitions for "efficient". Given your definitions, sure, I'd agree with your rephrasing. Those are not my definitions, however. Efficiency, in my little world, basically boils down to "doing more with less" -- less time, less RAM, less storage, whatever.

Sterling chip Camden
Sterling chip Camden

Part of the price of optimization is specificity for the task. If you need flexibility, then part of its price is usually some degree of performance.

Sterling chip Camden
Sterling chip Camden

Ken Lidster taught me that principle, and it often helps to work out the details of a design before coding begins. The only time it doesn't work is when your task is so research-based that you aren't going to find out how you need to do it until the attempt is made. Then you have to go back and fix the comments, and I'm sorry to say that edited comments never read as well as when they're written from scratch.

Tony Hopkinson
Tony Hopkinson

You wouldn't have said this. The real problem in commercial programming is the resource required to do self documenting code or document code isn't there, and in general if you are honest about it, never was. Most of us involved in the discussion, remember your halcyon days of yore all too well, though probably not as fondly. I started learning to code in 76, you seem to have stopped in 66.

auogoke
auogoke

as you have noted, @charlie204 has basically reaffirmed your message/point!

apotheon
apotheon

Maybe they're trying to optimize some disk-bound operation, after having prematurely optimized the system for some other assumed bottleneck.

apotheon
apotheon

You have to have a performance issue to have a reasonably measurable bottleneck. You need to have a reasonably measurable bottleneck to know what to optimize. If you don't know what to optimize, making assumptions about what you should optimize will often have the opposite of the desired effect; you may end up with a highly inefficient application, precisely because you considered efficiency first -- before you even knew what components most needed optimization. In short, you hit the nail on the head, Tony.

Tony Hopkinson
Tony Hopkinson

And it's one that needs to be at the forefront of your work from day one, otherwise you'll optimise it out. Int versus a Guid for an identifier for example. There are aspects of good design that will make it possible, such as modularity. One of the resoans scalability is so hard, is quite often you don't discover you really DID need it, until you are successful. And you got to be successful by being optimised to to the size you started at, and by leaving it until later....

Sterling chip Camden
Sterling chip Camden

Efficiency (or scalability, if you will) has more than one dimension. You can't please all of them all of the time.

Sterling chip Camden
Sterling chip Camden

As in "able to produce the effect". Common usage adds the bit about using a minimum of resources.

apotheon
apotheon

Good lord, what a horrible idea. It tends to result in reams of comments that bear little or not relation to the actual code and system design. This is the essential problem with BDUF, but with the added problem of mandating a bunch of soon-out-of-synch documentation within the code too.

Sterling chip Camden
Sterling chip Camden

Unfortunately, the TR web site could serve as an object lesson for a lot of things. If only we were allowed to look at the code...

Sterling chip Camden
Sterling chip Camden

In the Synergy/DE language on Windows, we have a runtime-bound DLL interface, which uses GetProcAddress to look up DLL routines when they're called. A seemingly reasonable optimization for this would be to hash previously acquired name/address pairs, but when we hacked up a prototype and tested it, we found absolutely no improvement, even over millions of calls. Apparently, GetProcAddress does something like that already internally, so our optimization would have been a complete waste of programmer resources.

Tony Hopkinson
Tony Hopkinson

but if you optimse for X and X is what you need then your program is efficient. So X is the requirement / goal, optimisation is the process, and efficiency is measure of how well you did it. Now you go look at your successful scaled code, and think how could I make that bit faster or leaner, a lot of options are out of the window unless you a prepared to say accept a lower limit on how far you can scale. I think what we can say is that there's a subset of the fundamentals of clean code that will lend themselves to an optimisation of any description, the members will shift about a bit though. The beauty of clean code is if it turns out you've inadvertantly de-optimised, fixing it will be a heck of a lot less expensive. A sudden thought, perhaps a better way of looking at it might be that there is a subset of clean code fundamentals which will survive an optimisation....

Sterling chip Camden
Sterling chip Camden

... scalability is one direction in which you can apply efficiency. You can also, for instance, apply efficiency to the problem of executing an algorithm as fast as possible, which may or may not have any meaningful impact on scalability. It can even be detrimental to scalability, if for instance your super-fast algorithm uses massive parallelism for each instance.

Tony Hopkinson
Tony Hopkinson

code is the way I'd put it. Equally true with security. Buffer overruns and such like are down to messy code, and or premature optimisation. But Const cnstPassword = "s3cr3T"; Password = cnstPassword; while at least fairly clean isn't a secure. Perhaps Nope, should have been Not the way I look at it. What I do know is if we successfully achieve secure and or scalable, the chances of our code not being reasonably clean are slim, very, very slim.

auogoke
auogoke

@Tony Hopkinson, Would it have been better if I said that scalability is "an integral component" of clean design/code? (I thought I covered that when I qualified my statement by noting that "... code that does not scale **when it should** is not really efficient.") I can see how developers may overlook scalability just as many(??) overlook application security. I agree that neither should be an afterthought in application development. Just as the article did not "abolish" optimization, it was not my intention to minimize scalability. My take on the original article was that, among other things, it tried to highlight the need to avoid the kind of mentality that leads to early and "premature optimization." I am struggling,,, but in "I don't think that's a nope", @apotheon makes it clear that there is a place -- a requirement if you will -- for scalability in clean design.

apotheon
apotheon

I think what auogoke was trying to say is that one achieves scalability by assessing what efficiencies are needed to ensure things scale to suit your growth needs, then making the necessary optimizations to achieve those efficiencies. Scalability is, in short, making sure that something that gets multiplied by absurd numbers as you scale up is a very, very small number -- and perhaps also making sure that the big-O increase as you scale up conforms to a very forgiving function. Thus, you ensure (well-chosen) efficiency, et voila: it scales. Yes, scalability needs to be a priority for cases where scalability is (known to be) needed. How you achieve it, however, involves tweaking for appropriate forms of efficiency.

apotheon
apotheon

I tend to use efficacious or effective with the "able to produce the effect" usage.

Sterling chip Camden
Sterling chip Camden

I've seen some extreme examples, even recently, of taking two days to figure out exactly what's going wrong, then another hour or two to figure out the right way to fix it, and in the end it's only modifying one line of code.

Tony Hopkinson
Tony Hopkinson

It's estimated that something like 60% (average) of the coding resource required to do it, is comprehending the existing code. Record how long it took you find the fault / come up with the enhancement without breaking something else, versus the actual time to code it. The numbers are scary , I've seen 99% on occasion. One famous occasion it took me two hours to change the caption of property of a Label component. Once I'd found out which one of the sixteen stacked one on top of the other in the designer, twelve of which had the same caption named label23 .. label38 and displayed by LEAVING only one of them visible through a myriad of separate functions, triggered every which way based on the content of a number of global variables.... Makes you want to scream....

Sterling chip Camden
Sterling chip Camden

Some folks use the comment count as a metric of software quality -- generally preferring a high percentage of commented lines. Perhaps that metric should also be inverted, and we should view the need for a comment as an indicator of poor code quality. Of course, it's difficult to assess in any automatic way whether code is highly readable or whether it's missing the comments it so badly needs.

Tony Hopkinson
Tony Hopkinson

I do doc comments in C# as they are very useful for inetllisense and the domain I work in (tax) is very opaque. In terms of comments as annotation, I view any as a failure to write readable code. There are occasions when I do fail (why I went down this route, WTFs, coping with funnies in resused code or libraries etc) and then I have no problem with adding acomment or two. I'm even happy to peer review and comment things that I thought were 'obvious', on the basis that they won't be in afew months time. What I absolutely refuse to do is to annotate instead of writing readable code. There is no excuse for that, takintg into account the limitations of the language you are using of course.

apotheon
apotheon

You've just described a basic rule of thumb I use: Code should be "self-documenting", in terms of how it works. Comments are for why.

Mark Miller
Mark Miller

In project after project I was noticing that I didn't have much time for commenting the code. So what I decided to do was "make it count for something." I kept my comments to a minimum. I'd talk about what the purpose of the module was, or if I created a class framework, generally describe what its purpose was. I'd put a comment where I thought what I decided not to do was important. I might say, "This is the reason I'm doing this, in case you're wondering." Lastly, if I did something that was highly unusual from the run-of-the-mill code for the type of application I was creating, I would write a comment about it, sometimes very large, explaining "the method behind my madness." Other than that, if there was a piece of code that was complex, I'd put brief comments about where the end of a function was (so that if you're at the bottom of the function, you can see where you are instead of having to scroll up to see the function signature), where the end of "if's" and loops where (for long, embedded code). Of course, in hindsight, one could say if your code is overly complex like this, that's a signal to refactor and simplify it. True enough, but that's if you have time for that sort of thing. It's my understanding that employers tend to not see the value in refactoring still. The only way in which I think my commenting strategy could've been improved would've been in the main module to talk about, "This is the purpose of this whole thing," and talk about the features and why they're there. I wrote up some documentation like that once (outside the code), and it was a realization to understand, "Oh, yeah. Someone new who's never worked at this company before would benefit from understanding what this thing is, and why it does what it does." I regret I didn't do more of that. So, rather than explaining the code, my general strategy was I assumed some things about the reader. I tried to target my comments to things I thought a programmer who understood the gist of what the product was about might be confused by.

Tony Hopkinson
Tony Hopkinson

The basic problem with comments to explain code, is that there is absolutely no way of guaranteeing that they do, and that keeping them in synch with the code (given that was ever true), doubles your maintenance burden. I flat out guarantte that this method will fail horribly in the real world, it won't happen or you'll go bust.

Editor's Picks