Geeks With Blogs
Chris Falter .NET Design and Best Practices

A colleague and I had a recent discussion about two versions of a trigger.  One was simple, containing a single query.  The other performed 14% better, but was a lot more complex--double the lines of code, and a branch that had to be evaluated.  My colleague advocated for checking in the more complex version right from the start, while I advocated for starting with simplicity.  What do you think?  Post a comment!

Here's how our discussion went:

COLLEAGUE:

Is your first example more than 14% more maintainable than the second example?  If not (which is my opinion, since there's really only one line, the "select inserted.NAME +..." line, that would change over time; the rest is boilerplate code), I think I'd go with the second for the performance increase.


ME:

My experience has been that it's a lot more expensive for an organization to maintain complex code than it is to tweak performance.  Additional complexity tends to work like Adam Smith's invisible hand--except that this invisible hand works for evil, rather than for good.  It makes staff spend more time trying to figure out how to fix bugs and add new functionality than they would with simpler code.  It makes the software organization slower to respond to customer requests and changing market conditions. 

The problem is that this complexity tax that the organization has to keep paying cycle after cycle is truly invisible because it is hard to quantify (unlike a small bump in performance).  But ask any developer whether s/he has had to spend significant extra time in development or troubleshooting because the code base was complex (i.e., whether s/he has had to pay the code complexity tax), and invariably the answer is yes, a thousand times yes.

Granted, a single trigger that improves performance by 14% itself will not cause all that hardship.  It's the cumulative effect of millions of lines of code that are a little too complex that make the development process harder and more expensive than it has to be/should be.

I guess the other way of pitching this philosophy is that if you tend to choose slightly better performance over simpler code,  when it comes time to optimize the system you're asking the question: which of these millions of lines of code could be simplified at only a small performance cost?  And we don't have the tools to answer that question very well.  OTOH, if we tend to choose simpler code over slightly better performance, then optimization means we're asking: where are the bottlenecks where we can get a big performance boost at a small cost in code complexity?  And we have a variety of profiling tools that help us answer that question very well.

COLLEAGUE:

I think you're letting a general philosophy get in the way of optimizing the one example you've shown.  A 14% improvement in performance is more than enough reason to have branching code that's only slightly less maintainable than the non-branching code.  I just can't imagine a scenario where a maintenance programmer sits down to fix a bug in this trigger and is so completely confounded by its complexity that fixing it would bring down the entire organization as you have suggested.

ME:

Actually, the maintainability difference is quite dramatic.  You're buying the slightly better performance at a cost of doubling the lines of code and doubling the cyclomatic complexity. 

Granted, this loss of maintainability occurs over a tiny portion of the code base.  On the other hand, the performance gain, measured as a percentage of total transactions against the database, is essentially imperceptible as well.  I.e., it's not as if a 14% perf gain in one of the most lightly used triggers among tens of thousands will amount to more than a sneeze.

What I'm saying is that the best strategy to optimize performance is to start with a good, simple code base, find the biggest bottlenecks in a realistic load test, and optimize just those code sections.  Usually, the vast majority of perf gains emerge from a small number of trade-offs against simplicity.

The opposite approach (always choosing performance over simplicity during initial development) results in getting to market more slowly (which has a cost), and--through the accretion of thousands of small complexities--a gnarly code base that is expensive and time-consuming to maintain.  The cumulative effect of small decisions makes a big difference.

If you look at this scenario in the small--one decision about one trigger--I can understand why you might choose performance over simplicity.  Now multiply that bias for perf over simplicity across dozens of developers writing code every day, and you end up with an entire system that is twice as expensive and time-consuming to maintain.  And the system would have lower quality to boot, since when you multiply lines of code and cyclomatic complexity, quality is pretty much lost at an exponential rate.  Such a loss of quality is surely expensive to an organization over the long-term.

That's why I advocate choosing simplicity as a matter of initial development.  Then as a QA process, look for the performance optimizations that will yield the biggest gains, and implement just those.  The 80/20 rule will apply: you'll get 80% of the performance gains, while giving up only 20% of the simplicity.

The problem of trying to go in the reverse direction is that we don't have very good tools for identifying which code simplifications can be purchased at the lowest performance expense.  So you just give up, and end up bearing all the expenses of a code base which is twice as big and twice as complex.  And those expenses are far, far greater than the expense of system performance that is a few percent slower.
Posted on Thursday, February 5, 2009 5:33 AM Coding Practices and Design Patterns | Back to top


Comments on this post: Simplicity vs. Performance

# re: Simplicity vs. Performance
Requesting Gravatar...
I think The Zen of python explains it well:

http://www.python.org/dev/peps/pep-0020/

"Simple is better than Complex" is much higher in the list than "Although practicality beats purity.". And of course, "readability counts."
Left by brad dunbar on Feb 06, 2009 6:58 AM

Your comment:
 (will show your gravatar)


Copyright © Chris Falter | Powered by: GeeksWithBlogs.net