Showing posts with label economics of software. Show all posts
Showing posts with label economics of software. Show all posts

Monday, 15 September 2008

Let My Textbooks Go!

There are three problems with prescribed textbooks:
  1. A generally low standard: Feyman's anecdote. Has anything changed since the 60's?
  2. An inflated sticker price: A NY Times article explains how textbook publishers are like big pharma.
  3. Limited content: So learn how to search the interweb!
Textbooks are starting to be given away for free. One free one that I have bought -- because I wanted a dead leaves version -- "one of the great classics of Computer Science" - Paul Graham.

This is free as in free beer, which addresses point 2. Point 1, the generally low standard, might be helped by more collaborative work on the content, taking a leaf out of the free software movement.

We'll see ...

Tuesday, 21 August 2007

Re-write or re-factor?

On individual projects I have usually found that a re-write leads to smaller, cleaner, faster solutions.

I attribute this to learning acquired from the previous attempts/versions, which I can incorporate in the form of improved abstractions and better trade-offs subsequently.

Some re-use of "golden nuggets" from earlier iterations may also be possible, and is certainly desirable.

Some lessons learned can be incorporated incrementally through re-factorings, but there are times when incremental improvement takes you to a local maximum and traps you there.

On big commercial projects other considerations come into play. Until the new code-base is up you need to contend with the cost of parallel development, and this period will be longer the greater the legacy. Unless, of course, your new abstractions are brilliantly efficient, and/or you can cut away a lot of stuff that was not needed.

Once a project is sufficiently large, given finite resources, it may eventually be too late to ever re-write!

Here's some more useful discussion by Adam Turoff on these issues prompted by survey question by Ovid.

Thursday, 14 June 2007

Pareto and The Wedding Reception Principle

Lately I have been thinking about points of diminishing returns, and perfectionism.

The Pareto Principle or 80-20 Rule says -- among other things -- that roughly 80% of benefit is derived from 20% of the work. Another statement is, "the first 90% of a task takes 90% of the time, and the last 10% takes the other 90% of the time".

Now, for maximum productivity, one should always pull-up short when the first 80% or -- thereabouts -- is covered, and move on to other tasks. But in practice there will be times when you need to go that last 20%. For example, if you are competing on quality, that last 20% is going to be important at least some of the time.

I have my own principle, The Wedding Reception Principle, which is even more useful than the Pareto Principle. It states that in any broad endeavour, if all aspects are up to a good-standard then people will be struck by the excellence of one-or-two outstanding aspects. On the other hand, if any one thing is sub-standard, that is what people will remember, regardless of whether everything else is exceptionally good.

For example, at a wedding reception, if the food is bad, that will be what everyone talks about, not how great the speeches were or how much fun the dancing was. But if the food was merely ok, and the speeches outstanding, it will be the speeches that everyone remembers and talks about, and their general impression will be positive.

In other words: Make everything good, nothing bad, and a few things extraordinary. And pick those things that you intend to be extraordinary carefully, because you will be fighting Pareto and spending lots of time on them. It would be a shame if they turned out to be relatively unimportant.

Wednesday, 25 April 2007

Quantifying the Cost of Feature-Creep

A naive person might think that the cost of building a software product with 100 features would be roughly 100c, where c is the average cost of a new feature. Unfortunately the real cost is proportionate to at least the square of the number of features, and may be much worse. Here's why ...

A Holistic View
No feature is an island. It interacts with some of the other features.

An easy way to appreciate the consequence of this is to imagine that the software product is being constructed incrementally, feature by feature. [In fact, this is not a bad approximation of reality.]

Each feature may have an interaction with a pre-existing feature. Therefore not only do we need to design and implement the new feature, we need to determine whether it interacts with each of the pre-existing features, and possibly modify them to co-exist with the new feature.

The cheapest case
In the cheapest case -- I won't call it the best case for reasons which will be described below -- all features are independent, and we simply pay the cost of being careful, i.e. checking that the new feature is independent of all the other features.

So the interaction cost is 0 + 1 + 2 + ... + n-1, for n features, which anyone who knows the famous story about Gauss can tell you is proportionate to n2.

So the overall-cost is n * average_isolated_cost + n2 * average_consderation_cost

The priciest case
What if the features are not independent? Not only do we incur the cost of modifying code associated with pre-existing features, but this may trigger a cascade:

Adding the nth feature may require a revision of code associated with the n-1th feature, but this code may also have supported all the other previous features! For example, disregarding the design-level interaction between feature n and feature n-2, there may be an additional indirect coupling via feature n-1. And there may be more distant indirect interactions too.

So in the worst case, adding a feature involves adding the new feature, modifying the existing features to account for direct interactions, and modifying existing features to account for indirect-interactions.

Note to the reader: Please let me know if you figure out a good upper-bound is: My hunch is proportionate to the factorial of the number of features.

Why the cheapest case is not the best case
In the cheapest case all features are independent. But in a cohesive software product you expect features to interact; so you would not want to design a product with this characteristic.

On the other hand you probably do not want all features to interact, because the end-result would seem overly dense, and consequently very difficult to learn to use.

Take home message: The degree of likely coupling of features is a consideration in both usability and cost.

What to do: Software Developers
The thought-experiments above do not reflect how developers actually determine how new features interact with existing features. However, determining these interactions is important. The following techniques may be of help:
  1. Reflection: A developer with a good theory of the product will be able to diagnose some interactions by thought, white-board, and poking around.
  2. Good Test Coverage: A good set of tests (e.g. built using TDD) will be of help in showing by failures of existing tests where a new addition interacts deleteriously, giving clues as to problems.
  3. Design by Contract: DBC-style assertions will give even better locality information than a test by showing where in the code the violations of old assumptions occur.
Of course, good abstraction and modularity of the code-base help too.

What to do: Software Designers
Of course the big message is to designers:

Choose your features carefully

The cost increases with the size of the product, so "just throwing things in", is a policy which will lead to great cost later. You can reduce this cost by attempting to do more with less: Aim for smaller feature-sets that do more with less.

Good luck!