Ok, so you've got some sort of performance problem. What do you do?
First, measure what's going on. The best thing I've found to use is some sort of sampling profiler that can go and sample all the threads and see what's going on. WebObjects applications have multiple possible bottlenecks, and its much easier to see what's going on with a 10 second snapshot of the stack then hours of speculation. The "sample" tool works particularly well with ObjC, but with Java you can use the Shark tools if you have access to the GUI.
Next, architect. Now that you know where the application is spending its time, backup a step and look at the system as a whole. Waiting for the database? Well, why are you doing so many database fetches? Can you optimize those away? At Marketocracy, we found that we were spending 1/3rd of the time doing date arithmetic which was mostly due to allocating/deallocating NSCalendarDates. Since we only needed one date per day, rather then optimized the date math, I made it so that we created all the dates since the beginning of the website at startup. 10K of memory made the site 30% faster.
Similarly, you have to design for scalability. It's not free. If your database is slow, and you have to do the fetches you're doing, then yeah, maybe you need to move the database to a faster machine. But maybe some parts of your system could live with a read-only replicated copy.
Finally, optimize. Sometimes, the right answer really is to optimize the code. But less often then you think. Optimizing can make something 10% faster, architecting can make something 10x faster.