Friday, March 11, 2005

Performance 101 - Avoid Work

We have a "performance" team at my day job. I am often unofficially assigned to this team when we are benchmarking a new release. While this is important stuff, I think more needs to be done to train the developers on performance basics.

First off, let me say that I do not consider myself an expert on performance. I do know how to analyze performance data and tune algorithms, but that's down in the details. I think someone experienced in performance begins with good design and then iteratively improves performance. The number one rule I tell people is the fastest way to execute a process is to NOT execute the process. Meaning, you should always be looking for a way to avoid work.

I'm going to explain a bizarre application to you now... we have millions of lines of PowerBuilder code that is still in production at over 100 companies worldwide. We started on Java several years ago and just over a year ago we cut the cord to the database and started sending all traffic thru the application server using XML over HTTP. Note that we were doing this to build a "merged-client" several years ago when SOAP was still something you washed your butt with, so we have yet to adopt it. This gives us a "psuedo n-tier" architecture that performs well on some things and sucks on others. Any kind of chatty process will suffer due to the extra network hop & xml parsing. Going XML may not have been the best idea in retrospect, but the performance is fine now. It just took a lot of tweaking to get there. The real problem is that extra network hop. If you came from a PowerBuilder or VB environment, you know how C/S apps work. Many of our processes were coded to act on a single row at a time & have performance issues now that the Oracle client is a hop away. Often the users identity is embedded in the SQL. (such as the user variable in Oracle)

Back to performance. When the client opens a transaction, the connection is stored in the http session. This works fine & we use SessionListeners to make sure things get cleaned up. Really haven't had too much trouble with it even though it is frowned upon as a practice. Now, sometimes the application is just running in a tight loop doing "selects" and not updates. (stupid, but that's how it was coded 6 years ago) The design was to return the connection to the pool after each request IF there was no active update transaction. That connection pool time becomes significant when you include having to establish the users "context" in the database to set their timezone, locale, and identity. The solution was to "avoid the work". I took the ConcurrentHashMap & DelayedQueue classes in JDK 1.5 and created a DelayedHashMap. The connection is stored in this DelayedHashMap & returned from there instead of the regular pool. After a configurable time, the object expires and is returned to the pool. So when we're in a tight loop situation, this constant need to reeestablish the users identity is alleviated and performance improves significantly.

The most effective way to speed up a process is to avoid it altogether.


Anonymous Anonymous said...

Hey that's my line!!! :)

You are quite right in saying that the best way to speed up a program is to get rid of unncessary work.

5:47 AM  

Post a Comment

<< Home