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…

Seven Deadly Sins of Programming – #6

May 31, 2006 at 11:14 am

Seven Deadly Sins of Programming – #6


Way back in my early career, I worked on a graphics program written in FORTRAN that was used to plot engineering data.


It ran on Tektronix 4014 terminals.


Our application – known as E.G.G. (Engineering Graphics Generator, one of a whole series of not-very-creative punny names used by the group) – used a menu-based approach. The user would place the cursor (moved by the thumbwheels on the right) over a menu option, hit the spacebar, and then the code would figure out what to do.


The internal architecture of the app was really pretty good. There were, if I recall correctly, 39 different screens, and each item on the screen had an id associated with it. The code would find the right item on the page, come up with a numerical code (menu number * 100 + item number), find that in an array of function pointers, and then call the appropriate function.


It worked fine, and allowed us to have a batch mode as well.


But after I started playing around with it a bit, I noticed that the command dispatch was a bit slow. After you selected an item on a screen, it took at least a couple of seconds for the screen to erase and redraw (this was running on shared Vaxen, so you didn’t get much CPU time, and what you got was fairly slow).


I did some digging, and found that the original developer (no longer with the group) had written the item lookup code using a Fibonaccian search.  This is a search that is similar to binary search, but doesn’t require complex operations such as divide by two or shift right (that alone should tell you the vintage of this search).


Such a search *may* have made sense on earlier systems, but on Vaxes, both the divide by two or shift right are in the hardware. So, we were using a search method optimized for constraints that we didn’t have that nobody in the group understood, in an attempt to be faster than binary search.


But it was a *clever* algorithm.


At this time, we had about 1200 items in our dispatch table. The first thing I did was build sub-index that stored the starting index of the first item in each menu, which meant the search space for a typical menu item went from 1200 items to about 30 items. The second thing I did was switch to interpolation search, which, given the nearly perfect distribution of items numbers within a menu (most menus had item numbers from 1-n, with very few holes), gave an almost perfect search. And it was code that most people in the group could understand.


So, the dispatch time went from a few seconds to about half a second, and I wrote up a “cost savings” in which I multiplied the number of users we had by the amount of time they used the application by the number of menu picks per hour, and figured out that I had saved the company around $30K per year. For which I got a $100 gift certificate.


So, what’s the point of that story?


Well, it makes me look good, which is the primary goal. It also illustrates that cleverness is an over-rated attribute of developers. How many times have you seen:


for (int i = 0, j =bounds; i < upper; i++, j += JUMP_SIZE)
{
    …
}


That’s somebody who is trying to be clever. They should have written:


int j = bounds;
for (int i = 0; i < upper; i++)
{
    …
    j += JUMP_SIZE
}


Which takes us on a long and tortuous trip to


Sin #6 – Inappropriately clever code


What examples of this have you seen?

Seven Deadly Sin of Programing – #7 – Excessive coupling

May 23, 2006 at 11:43 am

(these will be in reverse order…)


#7 – Excessive Coupling


We start out with a simple one.


Coupling is obviously a necessary evil. The Console class, for example, wouldn’t be able to send text through Win32 without being coupled to Win32.


Given that, less coupling is nearly always better that more coupling. A few cases that I see:



  1. Using switch statements rather than polymorphism or interfaces.

  2. Classes that do too much, rather than being focused on a single goal.

What do you think? Do you have more examples?

Random sometimes, not random other times

May 19, 2006 at 11:43 am

From a email:


private void button1_Click(object sender, EventArgs e)
{
   Customer c = new Customer();
   c.Randomize();


   Customer b = new Customer();
   b.Randomize();


   MessageBox.Show(string.Format(
        “object c random number = {0}, object b random number = {1}”,
        c.RandomNumber, b.RandomNumber));
}


public class Customer
{
   private int random = 0;


   public void Randomize()
   {
      Random r = new Random();
      random = r.Next();
   }


   public int RandomNumber
   {
      get { return random; }
   }
}


If I run the above code without debugging it always returns the same random number, but if I step through the code I get different random numbers.


******


This is a variant of a question that comes up fairly often.


When you create an instance of the Random class, the pseudo-random number generator needs to be seeded with an initial value. Some generators always seed with zero, which means you always get the same sequence of numbers. The .NET Random class seeds using the time, which means you get different results from run to run without having to set the seed yourself.


It also means, however, that if you create two Random instances one right after another, the seed value (I think it uses GetTickCount()) hasn’t had time to change, and you get the same sequence. But if you run it in the debugger, enough time passes between the creation of the two instances that you get different seeds and different numbers.


I think the best solution here is to move the Random instance to a static field:


static Random r = new Random();


And then just use that instance of Random from all the Customer instances.

My favorite driver’s ed moment

May 18, 2006 at 3:23 pm

One of the comments on my last post reminds me of a story.


Back when I took driver’s education  – which would have been the fall of 1979 – one of the modules of the class was spending time in the “simulator”.


I used quotes around term “simulator”, because what it really was was pretend driving. Less like playing a first-person driving game – not even like playing Pole Position – but more like playing with one of these:


But less interesting…


Here’s how it worked.


You sat in a room with about 12 other students. In front of you you had simulated controls – there was a speedometer, a steering wheel, turn signals, brake, and accelerator. At the front of the room there was a movie screen, on which you would watch a movie taken out the front of a car, and while watching, you would pretend to drive.


The sole feedback system consisted of a red light on your console. If the system – assuming it’s not to grandiose to call $2.00 of electronic components a system – thought that you were outside the acceptable parameters, it would light up the red light, and you would come to the attention to the drowsy shop teacher who had to get up at 4:30 to run this thing. I think it also logged your non-compliance, probably using cuneiform.


Each of the consoles had a speedometer, which ran off a motor which got its input from the accelerator and throttle. That helped everybody develop the all-important skill of keeping their fake speed correct.


Rudimentary motor control skills were enough to be compliant in most cases – presuming you could figure out what was coming up in the old, scratch movie. One day we were doing some freeway driving – which meant I was “traveling” at the highly patriotic double nickel – and we got into an interchange to go onto another freeway.


Or at least that’s what I thought it was. But it turned out that it was a right-turning exit that ended in a stoplight. By the time I realized that, I only had about a second before the car was coming to a stop. I spun the wheel, started braking, and as the car in the movie stopped, I looked down, and noticed that my speedometer was dropping through 40 MPH. It took at least another second before it dropped to zero.  I took a deep breath, and waited for the approach of Mr. Schmeer.


And the red light stayed off.


Turns out that the system didn’t check for your speed – only for your inputs. I was on the brakes as I came up to the light, and that was good enough for it. Similarly, if you were turning to the right, it didn’t differentiate how far you turned. You just needed to turn.


Simulator class was a lot more fun after that.

The Seven Deadly Sins of Programmers

May 16, 2006 at 12:53 pm

A while back, I made an offhand comment about something being one of the seven deadly sins of programmers (/programming/developers/software engineering/coding/…).


At the time, I really didn’t have 7 things in mind, but after a little thought, I came up with what I think is a good list.


But before I write the first entry, I’d like you to spend 5 minutes and write down your list of deadly programmer sins. Though 7 is the canonical number of sins, your list can have any number of items. After I’ve gone through my list, I’ll do another post where you can share your list.


[Update: Sorry I wasn’t clearer. Write your list down, and then post it when I’m finished. Or post it now on your own blog if you’d like]

Mom and Apple Pie…

April 4, 2006 at 11:47 am

A few days ago Rory wrote a post entitled Ten Minutes of Sincerity – Enthusiasthma, in which he argues that there is such a thing as too much passion.


Which got me thinking about one of my pet peeves. What do following words all have in common:



  • Passion

  • Innovation

  • Synergy

  • Agility

They’re what I call “Mom and Apple Pie” words, for two reasons.


First, they all have a positive connotation. Who wouldn’t want to be more agile, more innovative? Who is going to argue against having a more synergistic approach? Shouldn’t everybody have passion?


Combine that with the fact that these words are used in a content-free environment, and you get a nice-sounding platitude that means nothing, but makes it sound like you are for changing things.


You don’t think we should have more apple pie? What’s wrong with you? Why do you hate your mother?


People who want to make an organization more agile don’t say, “We’re going to improve agility”. They say, “we’re going to get rid of <x>, we’re going to change <y>, we’re going to release every <x> months”.


People who want to improve synergy say, “Our users are trying to do <x>, and it’s way too hard. What do I need to do to help you fix this?”


With those sorts of people, you can have rational discussions about the benefits and disadvantages of changes.


But don’t talk to me about being more agile or innovative without specifics.


BTW, I’m all for Mom, but I prefer Apple-blueberry, because I like the extra tartness…

Worst… Code… Ever…

March 16, 2006 at 12:24 pm

Like many developers, we enjoy making fun of other people’s code. I’ve had lots of those discussions over the years. And when it comes to who has had to work with the worst code, I’ve never lost.


Way back when I was just out of college – when 7-bit ASCII ruled the world, and people hadn’t decided whether lowercase characters were a fad or not – I worked for a Large Seattle Aerospace Company, at Large Seattle Aerospace Company Computer Services, in a group that built graphics tools for engineers.


One of the libraries that we owned was generated code.


Now, I don’t hate generated code. The Windows Forms Designer and I have a generally felicitious relationship. I even have a patent cube (which you get when an application is accepted at Microsoft) sitting on my windowsill that is related to an architecture for doing generated code.


This particular library was special. It goes without saying that the source to the generator was lost in the card recycling bin of time, but that was not what made it unique.


First of all, it was in FORTRAN. And not that namby-pamby FORTRAN where you can have modern control structures, this was FORTRAN 77, and you had better know how to count spaces and what it meant to put a character in column 6. Did you think that python came up with the idea of significant whitespace? Pshaw.


Secondly, the programmer who had written the code generator was a bit of a FORTRAN afficianado. There’s a feature in FORTRAN 77 known as the “assigned goto”. Here’s an example:


      ASSIGN 30 TO LABEL
      NUM = 40
      GO TO LABEL
      NUM = 50                ! This statement is not executed
30    ASSIGN 1000 TO IFMT
      PRINT IFMT, NUM         ! IFMT is the format specifier
1000  FORMAT(1X,I4)
      END


Now, to understand this, you have to remember that by default, any variable that starts with the letters I-N is implicitly an INTEGER variable (all others are implicitly REAL). So, you can assign 30 to LABEL (this is *not* the same thing as writing LABEL=30, which means what you expect it to mean), and then use “GO TO LABEL” to goto 30.


Suffice it to say that the developer had never read Dijkstra.


Now, my guess is that while the vast majority of you are thankful that you don’t have to work in FORTRAN, there is a divide in opinion beyond that. Some of you are saying “Well, that’s not really that bad”. But the rest of you are shaking your heads, because you know what is coming.


When you’re doing code generation, you need to somehow come up with variable names. In this case, the developer took the easy way out, and all integer variables were something like “I1344”.


And line numbers also use the same range, starting at 1000 and going on up.


So, it means that the code has lots statements like:


GO TO 11634


and lots statements like:


GO TO I1655


Did I mention that in the fonts of the day, the difference between “1” and “I” was fairly subtle? Even if you did notice the I in front, you had to cope with the fact that


GO TO I1655


really meant


GO TO 3455


At least, it meant that sometimes, but I1655 would be re-assigned when the program ran.


IIRC, there were about 15K lines of this in library.


So, bother me not with tales of poorly-formatted C# code or 2000 line C functions. They are mere trifles. To snatch the rock from my palm will require something stronger. Are you up to the challenge?


(I am a bit worried that there might be some LISP or APL programmers out there…)

The capability immaturity model

March 15, 2006 at 11:59 am

I was reading the DailyWTF this morning – a great read, BTW – and came across a link to the Capability Im-Maturity Model, which I thought you might enjoy.