Debugging is twice as hard as writing the code in the first

Posted by jmls on 20-Feb-2011 15:55

for those of you who have been following my ramblings over the past couple of weeks, I have reached some "interesting" conclusions.

I found myself tonight congratulating myself on how clever I was, because I had worked out a way of having a base class that could handle all of the crud operations of a value object , passing them onto the appropriate library , and all without any knowledge of the library itself. The Value objects inheritied this base class and only contained the properties themselves. This was just so cool. Everything just "worked". I could create a new Valueobject, create the library and everything worked itself out.

Sufficient to say, the base class was strewn with DYNAMIC-INVOKES, STATIC methods and properties. It wasn't a very pleasant read. However, I tried to document it as well as I could, knowing that in some point in the future I would be back to revisit the code.

I was just about to hit the "commit" button when the old saying hit me

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." --Brian Kernighan

I sat back and decided to analyse why I was so hell-bent on making this as smart as possible. Over the course of the evening I destroyed all of my perceived views and came to a very simple conclusion.

This was way, way more complicated than it ever needed to be. I was trying to save memory. I was trying to save CPU time.I was trying to be oh so clever etc etc

However, at the end of the day, I was being an Idiot.

Basically, the final realisation came when I ran the numbers.

If I can create 48k of objects per second using "simple" code (a value object with properties and CRUD methods in the same object), or 50k of objects using "incredibly clever, complicated" code (a value object with just properties, and proxy methods passing control to the appropriate method libraries), then the answer is obvious, even to an old assembly developer like me.

Make it easy to understand and fix, even if it takes 2x the memory and is "only" 96% of the speed.

I should also mention that trying to make it as small and as fast as possible has cost me the weekend. I could have been doing a lot more productive stuff 

A salutory lesson. One I am going to remember.

All Replies

Posted by Thomas Mercer-Hursh on 20-Feb-2011 16:22

Congratulations on your epiphany!

When I read the title, I thought this was going to be a complaint about the difficulty of debugging and my mind went off on a tangent which, in the end, is not unrelated to your own "discovery".

For many, many years, I have had relatively little use for debuggers since I have long sought to write code in a way that there was a very clear relationship between a "job" and the piece of code which did that job.  So, when something didn't work right, I knew immediately where the error had to be and could very often find it by a quick inspection, much more quickly than I could have found it tracing through with a debugger or similar approach.  Needless to say, it wasn't perfect and there have been times that I have had hair tearing sessions, especially when dealing with legacy code, but it has worked a lot.

There is, of course, a strong synergy here with good OO ideas.  One object, one responsibility.  If there is something wrong with the way the responsibility is being fulfilled, one knows exactly "who" has to be at fault.  There is a lot to be said for simplicity and directness.  Getting clever rarely means simplicity and directness.

In the same vein, I don't find myself attracted by these efforts people get into of writing incredibly complex dynamic code with the idea that they will never have to write that code again for a new table or object or whatever.  One has certainly created a maintenance nightmare and all the cases which were actually simple are now bound up with this thing that is incredibly complex.

If one wants to save effort in routine coding, much better to put energy into model to code translation.  Have the translator produce simple code.  Life is much easier.

Posted by Admin on 20-Feb-2011 23:54

Debugging your own code ages later is three times as hard ....

Debugging somebody elses code is four times as hard ...

There can't be enough clearness in code.

Posted by Thomas Mercer-Hursh on 21-Feb-2011 11:20

Well, I think that depends.  I have written code which was easy to debug, both at the time and later.  And, I have written code which was ghastly ... probably the worst case being a short fling with APL where I wrote what should have been a several thousand line program in something like 10 lines ... including the IO!  I can't imagine ever figuring that out again.  And, in the same vein with respect to other people's code ... it depends a lot on who the other people was.   If it was someone who wrote nice clean code, it can be a positve pleasure reading it.  Or, it can be a nightmare where one is ahead of the game figuring out what the code needs to do and scraping it in favor of new code.

Posted by marko.rueterbories on 21-Feb-2011 11:26

Vom 21.02. - 26.02.2011 bin ich nicht im Büro erreichbar. Bitte haben Sie Verständnis, dass ich Ihre Email nicht zeitnah beantworte.

In dringenden Fällen wenden Sie sich bitte an Herrn Fechner (mailto:mike.fechner@consultingwerk.de).

Mit freundlichen Grüßen / Kind regards

Marko Rüterbories

Posted by Admin on 21-Feb-2011 11:46

Well, I think that depends. 

It always depends on who wrote the code the first time - and how much effort he spent making it easier to understand the code later on.

But in every case, it's much easier to understand your own code immediately than years later - ideas will be much fresher after you wrote it. And for the code of a stranger all you have is the code and eventually documentation. No ideas about the original developers intentions were left for eternity beside that.

Posted by Thomas Mercer-Hursh on 21-Feb-2011 11:57

Unless, of course, the other code came from some model to code process and then one has nicely documented use cases, requirements, requirements traceability, models of how the code is supposed to interact, etc.! 

This thread is closed