Googles appar
Huvudmeny

Post a Comment On: cbloom rants

"01-22-10 - Exponential"

6 Comments -

1 – 6 of 6
Blogger won3d said...

One semi-related way to think about exponential complexity in programs is test coverage. Getting 100% test coverage is pretty clearly O(size of program), but what does that buy you? It doesn't cover each scenario for which your code is used.

Something truly exhaustive would be path-complete testing. The number of paths in your program is big-O exponential, but that isn't a very tight bound. In reality, not all of your paths are independent. Perhaps one path excludes another, or 2 paths commute because they affect independent state.

I think the essence of good software design is making your different paths as orthogonal (there's another word that can become a pet peeve...) as possible, to keep the non-linear term as small as possible. This, of course, matches my intuition, or maybe is just a roundabout way of justifying it.

January 22, 2010 at 7:36 PM

Blogger ryg said...

Nitpick first: Geometric growth is exponential, not quadratic (The definition of a geometric progression is that x_(n+1) / x_n = const for all n). I don't think there's a commonly used synonym for quadratic growth.

On the actual subject: Games have the big advantage that most of their essential (behavior-determining) interactions take place between components that are part of the codebase. The same isn't true for most web apps, for example, and I suspect that goes for most business apps too, though I have no experience on the matter. Web apps are completely dependent on several black boxes (web server, DB engine, network and IO subsystems of the kernel, ...), usually with several caching layers inbetween that accumulate hidden state all over the place (some of them completely out of your control, like in the browser), and all of these pieces interact behind your back in nonobvious ways.

This kind of construction is most definitely a bug magnet, and basically everyone has given up on fixing all but the most obvious bugs. Basically all big websites I know will occasionally barf, displaying an error message in the vein of "so this didn't work, but just hit Refresh to make me try the same thing again and I guess everything will be okay". If this kind of shit would happen in one of my "real" programs, I'd be terrified.

(PS: Blogger just told me that "Your request could not be processed. Please try again." while trying to post...)

January 23, 2010 at 5:52 AM

Anonymous Anonymous said...

Yeah, I agree with ryg, there's an unfortunate redunancy between 'geometric' and 'exponential'. To refine his comment, I'm not sure how "geometric growth" is officially defined, but there is absolutely a thing in math called "a geometric sequence", the elements of which can be defined with an exponential function.

But none of this changes the fact that almost nothing is exponential growth. (Or, thus, even geometric growth.)

Anyway, there is absolutely no way I have tested anything resembling N^2 features of my current project. The size of my tests are probably closer to O(N).

I'd argue that the use of abstractions and black boxes are designed to bring complexity to be something like O(N log N); i.e. you're making a hierarchical tree of abstractions.

You get some cross terms, the tree isn't binary and may cross levels, but I think that's true to a first approximation.

Whether that means you really need O(N log N) tests or O(N^2) or O(2^N) tests I dunno.

Another way to do this is to look at the math. If you can have M bits of input, then you have at most 2^M possible test cases. To be 100% sure of tests, you have to test all 2^M test cases, and this is true regardless of how big N is. How far short of that are you willing to stop?

Anyway, my guess is that software complexity for N features is something like O(N log N), and # of bugs is something like O(LOC * something-that-grows-slower-than-log-N), but the problem is how much testing you need to find those bugs.

January 23, 2010 at 10:42 AM

Blogger cbloom said...

Yeah I should definitely be saying "polynomial" instead of "geometric".

I think if you could measure your dev complexity vs. your feature count that would be a good measure of how good you are as a coder. That is, if your abstractions are perfect, you can do N features in NlogN dev cost, if your abstractions suck it takes N^2 dev cost.

Also, Sean, I don't think your data point is valid yet. Pretty much all decent devs can initially write N features in NlogN time, but most people underestimate the long term cost of features in bugs and support over the life of a product. Does that become N^2 over the long run? Hard to say. (for example, how does the # of stupid questions from clients scale? is that N^2 ?)

January 23, 2010 at 12:44 PM

Blogger Thatcher Ulrich said...

Besides lines of code to implement N features I think there is another superlinear cost -- designing a reasonable UI. That can be pretty vicious. Dunno if it's actually exponential.

January 24, 2010 at 6:16 AM

Blogger Sean Barrett said...

Pretty much all decent devs can initially write N features in NlogN time

To clarify, I absolutely didn't mean NlogN time, just NlogN in size (or some complexity metric). And I agree that maintainence and support time should be measured when considering time (or equivalently cost).

Also, O(NlogN) size isn't from just the current project, that's my intuition drawn from a lot of projects. I only brought up my current project to point out that I doubt anybody does O(N^2) testing.

(stupid openID server be borked)

January 25, 2010 at 7:16 AM

You can use some HTML tags, such as <b>, <i>, <a>

This blog does not allow anonymous comments.

Comment moderation has been enabled. All comments must be approved by the blog author.

You will be asked to sign in after submitting your comment.