Thursday, May 15, 2008

The Myth of SLOC

Ah, that old favorite metric, Lines of Code, all the ubiquity of a spork and slightly less useful. Since we all (hopefully) know that SLOC is a useless metric, the obvious question is why would anyone use it? The simple answer is that it's so easy that a drunk chimp can calculate the metric!

As an example of why SLOC is useless, imagine two programmers at different companies implementing a paging functionality. Specifically, both programmers need to determine whether a next button and a previous button should be displayed. Programmer A produces the following code:

String n,p;
if(x&&y) {
n="enabled";
p="enabled";
} else if(x&&!y) {
n="enabled";
p="disabled";
} else if(!x && y) {
n="disabled";
p="enabled";
} else if(!x && !y) {
n="disabled";
p="disabled";
} else {
n="disabled";
p="disabled";
}


Wow, 16 lines of code! Programmer A's been pretty productive. Programmer B, on the other hand, came up with:

String next = hasNext ? "enabled" : "disabled";
String prev = hasPrev ? "enabled" : "disabled";


Wha? Only two lines of code? What a slacker! Oh, wait... both ultimately have the same effect! In fact, on closer examination, we find that Programmer A's code actually reduces the value of the code base! In case you're wondering how adding functionality could reduce value, consider the cost of maintenance. Those 16 lines, including a logically impossible else clause, will have to be read and understood by some poor soul if that file ever needs to be changed. Since none of the variables have meaningful names and the boolean clauses are more complicated than necessary, understanding Programmer A's code will take significantly longer.

So, if more lines of code aren't better, doesn't that mean that expressing the same thing in fewer lines of code is better? Turns out that the answer is a resounding... not necessarily. I'll expand on that a bit more in the next post, including touching on the myth that fewer lines of code implies fewer bugs.

Wednesday, May 14, 2008

Dev102.com Programming Challenge 3

Programming Challenge 3 at Dev102.com is to find an element in a mxn matrix whose rows and columns are sorted in ascending order. A quick and easy way to do this is to perform a binary search in the first column to find the row with the highest value that is less than or equal to the value for which you're searching. Then, perform a binary search in that row to find the element.

If that didn't find the element, then do the same thing except perform the binary search on the first row and then the column. You can actually use information from the first run to limit the size of the size of the column, but the performance improvement will (in general) be relatively small.

The runtime for this is O(log m + log n)

Tuesday, May 6, 2008

Dev102 Programming Challenge 2

Programming Challenge #2 at Dev102.com is to find an efficient way to reverse the bits in a 1000x1000 byte image. Assuming you can afford 256 bytes for a cache, one really fast general-purpose way to implement this is to create an array with an entry for each possible value of a byte, storing the reversed bits of the byte. For each byte in the image, you can then look the reversed bits nearly instantly. The runtime of the algorithm is O(n) with a trivial constant multiplier.

This algorithm, by the way, is insanely easy to make run in multiple threads and should run extremely fast on a multi-core SIMD processor.

The Only Process You'll Ever Need

Scrum, CMM-I, ITIL and countless others. It seems that for every developer, there are half a dozen software development methodologies and processes. Some are lightweight, some are heavyweight and some are stupid-weight, producing orders of magnitude more documentation than code.

So, you may be wondering, why are there so many different processes? The answer is that everyone's looking for that one, magical process that'll make software development predictable and repeatable. Unfortunately, I don't have that magical process to give you, in fact, I seriously doubt that it even exists. What I do have for you however is a process without which your development efforts are guaranteed to fail. The process that I have for you is a very strict process, far more strict, in fact, than most heavyweight processes, but it requires no more documentation than your handwritten notes to yourself.

I won't keep you in suspense anymore. This super-process is none other than the scientific method. In case you're not familiar with the scientific method, here are the highlights.
  1. Consider the problem
  2. Gather data
  3. Formulate a hypothesis (an educated guess about how to solve the problem)
  4. Test your hypothesis
  5. Use the information from testing your hypothesis to accept, reject, or refine the hypothesis
The scientific method is useful at all stages of software development, but it is particularly useful when debugging, which is frequently the most difficult part of development. Before fixing a bug, any bug, take some time to apply the scientific method. Think about the bug and what the implications of it are. Don't jump straight into the fix, spend some time to make sure your fix will really fix the problem and not just mask the symptoms. Figure out how you'll test that your fix actually works without breaking anything else, and then test the fix. If it works, commit the fix and do the dance of joy!

Good luck and enjoy your coding!