The mythical book, Mythical man month quoted that no matter the programming language chosen, a professional developer will write in average 10 lines of code (LoC) day.
After a bit more than 6 years of full-time development on the tool NDepend I’d like to elaborate a bit here.
Let’s start with the definition of logical Line of Code. Basically, a logical LoC is a PDB sequence point except sequence points corresponding to opening and closing method brace. So here we have a 8 logical lines of code method for example:
See here the post How do you count your number of Lines Of Code (LOC) ? for more details.
I already hear the bashing; LoC has nothing to do with productivity, Bill Gates said “Measuring software productivity by lines of code is like measuring progress on an airplane by how much it weighs.“.
And indeed, measured on a few days or a few weeks range, LoC has nothing to do with productivity. Some days I write 200 LoC in a row, some days I spend 8 hours fixing a pesky bug by not even adding a LoC. Some day I clean dead code and remove some LoC. Some other days I refactor exiting code without, all in all, adding a single LoC. Some days I create a large and complex UI Form and the editor will generate automatically 300 additional LoC. Some days are dedicated solely to performance enhancement or planning upcoming code architecture…
What is interesting is the average number of LoC obtained from the long term. And if I do the simple math I obtained around 80 LoC per day. Let’s precise that I abide by high code quality standard. Each LoC must be covered by unit-tests + all possible code contracts must be declared (of course, not all LoC can, nor should, be checked by contracts and some classes are nit relevant for unit-testing, especially UI related classes).
So this average score of 80 LoC produced per day doesn’t sacrifice to code quality, and seems to be a sustainable rhythm. And what is really cool with LoC, is that, once calibrated, caring about counting LoC becomes an accurate estimation tool. After coding and measuring dozens of features achieved in this particular context of development, the size of any feature can be estimated accurately in terms of LoC. Hence with a simple math, the time it’ll take to deliver a feature to production can be accurately estimated. To illustrate this fact, here is a decorated treemap view of most NDepend components.
Thanks to this treemap view, I can compare the size in terms of LoC of most components. Coupling this information with the fact that the average coding score if 80 LoC per day, and looking back on cost in times for each component, I have an accurate method to tune my way of coding and estimate future schedules.
Of course not all components are equals. Most of them are the result of a long evolutive coding process. For example, the code model had undergone much more refactoring since the beginning than say, the dependency graph for example that had been delivered out-of-the-box after some weeks of development.
There is something else interesting this picture is telling. I can see that all these years polishing the tool to meet high professional standards in terms of ergonomy and performance, consumed actually the bulk of LoC. For example just having a clean Project Properties management is implemented through (model + UI control) =(3.751+2.686) = 6.437 LoC. While a flagship feature such as the interactive Dependency Graph only consumes 2.897 LoC, not even a half of the Project Properties impelmentation. Of course the interactive Dependency Graph capitalize a lot on all the existing infrastructure developed for other features. But as a matter of fact, it took less effort to develop the interactive Dependency Graph than to develop a clean Project Properties model and UI.
All this confirms an essential lesson for everyone that wishes to start an ISV. It is lightweight and easy to develop a nice and flashy prototype application that’ll bring enthusiast users. What is really costly is to transform it into something usable, stable, clean, fast with all possible ergonomy candy to make the life of the user easier. And these are all these non-functional requirements that will make the difference between a product used by a few dozens of enthusiast users only, and a product used by the mass.