Seven Deadly Sins of Programming – #4

June 26, 2006 at 5:38 pm

Our next sin is the one that I’ve certainly been prone to.


Long ago my wife and I owned a house east of Renton, Washington (those who know about Renton at that time can probably understand why one would say “east of Renton”).


Like many homes, this one had had various indignities committed on it by the previous owners. One of the most obvious was what can only be described as a “lean-to”, constructed out of surplus Boeing shipping containers and shielding the washer and dryer from the rest of the garage.


After dealing with cold and dirty feet for a few months, we decided to convert the space to a real room, with features such as a floor, a laundry sink, a ceiling that was actually attached to the joists, etc. The framing went quickly, but when it came to the point of finishing the drywall, we ran into a problem.


My wife and I had very different ideas of how smooth a wall should be before it was painted. She wanted it to be mostly smooth, while I spent a fair amount of time with a light at an oblique angle, trying to get it really smooth.


I did the bulk of the drywall finishing myself in that room.


And after it was all painted, it turned out that it didn’t really matter. Her standard was fine.


Which leads us, in the usual roundabout way, to our destination:


Sin #4 – Premature Optimization


Or, in other words, spending time on things that don’t really matter in the end.


It’s happened to all of us. You’re in the middle of writing a class, and you think “a linear search of an array just isn’t going to be fast enough here”. So, you spend some extra time, and you use a hash table, or a tree, or a binary search, or something like that, and when you’re done, you say to yourself, “now *that* isn’t going to cause any problems”.


And then later, when you’re getting close to done, you run your code through a profiler, and you find that a) the array never has more than 3 elements and b) the code is spending a ton of time elsewhere in the code.


You wasted the time that it took you to do the optimization (bad), and you may have ended up with code that is considerably harder to read (worse), depending on how much optimizing you did.


How do you avoid this? I have two bits of advice:



  1. YAGNI came out of XP, and it’s a good dictum to follow. If you are doing TDD, this is easier to do as you are more focused on making one small change and not on “finishing the class”.

  2. Go read what a wise man has said about performance, and work on creating a performance culture in your group.

Seven Deadly Sins of Programming – #5

June 15, 2006 at 6:29 pm

[Several readers pointed out that I made a mistake in phraseology, and didn’t say the thing I meant. Thanks to them for knowing what I wanted to say more tha I did.]


Thanks to all who have commented on the previous sins, and to those who have written their own lists. I have avoided reading them, but I will take a look when (if…) I get done with my list, and I’ll write a summary post linking to them, and likely listing the ones that I would have put on my list if I’d only been a bit smarter and a bit more thoughtful.


Back when I was a pre-teen, I thought I really knew what was going on. I didn’t need my parents advice on what to eat, or who to hang around with, and I *certainly* didn’t need their advice around oral hygiene.


So I didn’t brush my teeth. Oh, I’d rinse my mouth out, but no actual brushing.


This didn’t cause any problems – my teeth were fine when I went to the dentist. No worries.


For a year or so. Then I had to have 4 cavities done in one fall. Big cavities. Cavities that weakened my teeth enough that I’m slowly buying my dentist some nice accessories for his boat, as they start to crack and I get crowns put on.


Code hygiene is also important.


Back when I started coding, my teacher (who I am in debt to for being at least 10 years ahead of his time and setting up a real programming curriculum (no, we didn’t use abacuses…)) made us write down our programs on paper before we were allowed to use computer time. Not only did you have to write it down, you had to show it to him, and if it wasn’t good enough, he’d make you copy it from scratch with the necessary changes.


When I got better, I got introduced to my first text editor. Line oriented, a real improvement. Rather than typing a line over, you could make changes to it.


Then, the fateful day came when I got to use a screen-oriented text editor. You just used the arrow keys, and you could make changes *right in your code*.


Very powerful. And very dangerous, because it supported


COPY AND PASTE


(Cue emphatic and scary music).


Copy and paste is not a sin – it’s actually quite a useful thing, but features like it make it far too easy to do bad things. Need a function that’s almost like the one you have? Copy and Paste. Need to add another conditional into that double-nested loop? Just insert it in there. Need a class that’s almost like what you have? File copy, then search and replace to change the names.


Which leads to too much function complexity and duplication, and to our fifth sin:


Sin #5 – Deferred Refactoring


Once you start deferring refactoring, things get bad. Even if you have good intentions to come back and “clean that up a big”, you often don’t.


That’s why I find agile methods and shared code ownership so interesting. If there are good tests in a codebase, I can find the ugly code that a coworker has written and refactor it into something nicer rather than just trying to get picked to work on “the new codebase”…


Now go brush your teeth, and it wouldn’t hurt you to floss sometimes…

A close escape, and more on inappropriate cleverness

June 2, 2006 at 11:53 am

Monday I went on the 7 hills ride.

Wednesday night, I wrote a long and detailed post about it, and hit the “Post” button.

In a fit of editorial brilliance, my blog server chose that exact moment to experience a problem, and the post vanished into the ether.

Few will quarrel that that event was a net positive for western civilization as a whole.

So, here’s the short version.

HomeDownPauseUpDownUpDownUpDownUpDownUpDownPauseUpDownUpDownStrawberryShortcakeUpHome

Now, that that’s out of the way, there were a few comments on the 6th deadly sin post that I’d like to comment on:

(BobHy) “Inappropriate” is relative to time (as your first story illustrates) and point-of-view (“cui bono”).  Would you agree that cleverness which benefits the user who runs the code (efficiency) or the team who maintains it (maintainability) is appropriate?  And if the clever bits trade off one of these against the other, who gets to decide the direction?  

Inappropriate is obviously a value judgement. Who decides? Well, I do, since it was my post. In general, I’d expect that the team would decide, though in my experience there aren’t that many teams with the sort of culture that allows this.

But, yeah, I agree with this.

(BobHy) OTOH, even when we consider cleverness whose only benefit is to amuse its author, it’s fair to ask whether the author’s happiness is itself a benefit to the user community (“a happy programmer is a cooperative, bug-fixing programmer”) or to the team (“a happy programmer remains on the team and trains his/her successor”).  

An ancient Chinese programmer once said,

I pity the fool who has to maintain or extend the code of a programmer who wrote clever code because it made him happy.

I’ve experienced many cases where a developer writes code that is clever, moves on to another job, and then the people who have to deal with the code have to deal with that cleverness. My current team is dealing with this now, and it’s a big problem for us.

If you want to amuse yourself writing clever code, do it on your own time. But don’t make your team deal with it.

(BobHy) I’m beginning to think “inappropriate cleverness” may be a vacuous term. But there certainly is “incorrect” cleverness, where the claimed benefit of the design is refutable.

You are obviously not a long-term reader (assuming, for the sake of argument, that such a person exists) if you find the presence of a vacuous term in a post of *mine* surprising.

The difference between inappropriate and incorrect seems mostly one of semantics. I chose inappropriate because I think it’s more of a judgement call, while incorrect implies a black and white choice.

(Tomer) It’s funny, I keep running into arguments as to the pros and cons of the sort of “codespace-optimized” loops you mentioned. I’m actually very much for them – they’re usually used where the algorithm is very simple (for example, when writing to a frame buffer and adding a stride value to your target pointer) and tend to make the code “look” a lot more elegant.

I will confess to being somewhat of a code aesthete in my earlier days, looking for more compact expressions. I got started in that back when I was writing games in interpreted basic, and the size of your code could have a big impact on how fast your program ran.

Over the years, writing a lot of code and trying to understand other people’s code, I realized that the #1 most important feature of well-written code is clarity. And for me, the two most important facets of that are:

  1. Predictability (the code in method a looks like the code in method b)
  2. Simplicity

The world where for loops just do looping is a conceptual simplification over the world where they sometimes do additional things. In the first case, I read the for statement once, and then concentrate on the loop body. In the second case, I read the for statement, read the loop body, but have to remember that there’s something else going on that I have to go back and refer to later. When you write that, you’re making me work harder, when you simply could have put “j += stride;” as the last statement in the loop.

That’s why foreach is such a useful construct. It’s not that you type less. It’s that it’s conceptually simple – you know that there’s no funny business going on, and all you have to worry about is the loop body.

(Shahar) We used to have a dev in a previous company I worked at (circa 2000) who had his own special way of doing HRESULT-COM error checking..

Shahar goes on to detail what the practice was, which I agree is bad, but it’s a matter of degree, since all HRESULT handling techniques suck.

*****

Most code is read far more times that it is written. Go read this post by Peter Hallam, one of the C# compiler devs.