General tips and guidelines for tuning code
Original content from this thread posted by Steve Souza.
1) Measure, don't guess - Often we guess wrong on what code to tune and end up wasting our time tuning code that makes no overall impact. Measure performance and go for those small sections of code that consume the most time. Measure your performance improvements and repeat the process.
2) Measure in production - You have no idea how your system is used unless you are looking at real user interactions. For example say you have 2 pages that each take 1 second to execute. In load tests you assume that each page will be hit the same number of times, but users think otherwise. Users may hit one of the pages an order of magnitude more than the other one. By measuring in production you learn which page should be tuned first. As a side note usually master pages are hit more than detail pages.
3) Build performance measurement collection into your application from the start - Web performance is difficult to understand looking in from the outside. At a minimum you should measure overall page response/execution time as well as calls to external systems like jdbc (see the jamon servlet filter mentioned below)
4) Use the JAMon servlet filter, it is your friend - I must admit I wrote this software and so I am biased, but by simply adding a few lines to your web.xml and making jamonadmin.jsp accessible you get many performance statistics such as: page hits, avg time, min time, max time. You also get concurrency stats like which pages are currently executing, what were the max simultaneous invocations per page. You also have correlations between performance and concurrency (i.e. this is a measure of scalability).
A few more things. JAMon is fast enough to be used in production systems (pretty much no overhead), it is part of your app so no special installation of software is required, it can monitor other aspects of your code such as jdbc too, and it is free. Because JAMon is part of your application it moves from dev/test/prod with no server environmental changes.
To see a live demo go to this page
To read more about JAMon, and monitoring in general go to the JAMon web site
5) The JAMon JDBC driver is your friend too - JAMon 2.2 introduced the JAMon proxy JDBC driver. It sits in front of ANY JDBC Driver and tracks aggregate stats for SQL Calls/JDBC Method Calls/SQLExceptions. As in all features of JAMon it is fast enough to be used in production systems. You can use the JAMon JDBC driver without chaning even one line of your code. An example follows with Sybase ASE:
The live demo and JAMon links are mentioned above.
6) And JAMon interface monitoring is also your friend - JAMon 2.1 introduced the ability to monitor ANY Java interface. You call your code as you normally would and JAMon keeps aggregate statistics for it. An example follows:
The live demo and JAMon links are mentioned above.
7) It's probably the database - A recent application that I worked on spent 95% of its execution time executing SQL. Of the 50 or so sql statements two of these queries accounted for 80% of the applications execution time! These 2 queries were tuned by adding indexes, and the application zipped along with NO code changes. Only 5% of the application execution time was due to java code. I find this to be pretty typical.
By the way a normalized database table can often out-perform a denormalized one as fat denormalized tables can require more IO. Also - Indexes are your friends.
8) If it's not the database it's probably some other IO - IO (database, network, file) will usually be your performance culprits, and not your java code. Tuning your jdbc driver, and network may help more than tuning your java code.
9) Learn to write good SQL - This is probably more important than any Java P&T tricks you can learn.
10) Some performance truisms:
11) Be wary of slow home pages - Home pages are often heavily hit. Have them perform minimal work (for example just display a menu). One application I work with has a home page that takes 2 seconds. I am rarely interested in the information that is on the home page and immediately go elsewhere. It would be a better design to have a simple menu come up, and avoid the 2 second penalty if many users want to do something other than the default home page action.
12) Don't microtune - An example of microtuning is when you have a web page that takes 1 second to execute, and you notice that you can tune a subset of this pages code and reduce this subsets execution time from 20 ms. to 10 ms. Congratulations, you've cut the execution time of this code in half! This sounds impressive, until you realize you have only trimmed the performance of your overall page by 1% (from 1000 ms. to 990 ms).
This tuning was a waste of time. Your time would have been better spent drinking a beer. Look for changes that give you the biggest bang for your tuning buck.
13) There are bad Performance Tuning Questions - The most common performance tuning questions I see on the java forums are purely academic, and make no substantive difference in real programs. Questions like: "Are statics faster than instance variables?", "Are local variables faster than instance variables?", "Are HashMaps faster than Vectors?", "Are while loops faster than for loops?",...
When we answer such questions without stating that they are purely academic, we do a disservice to the development community by perpetuating the idea that microtuning is the place they should focus their attention.
14) It's not average execution time - it's total time - If you don't know the frequency of your codes execution (hits) then you won't know which page to tune of two pages that take 1 second to execute. If you know one page is executed 10 times a day and the other 10,000 times a day you would.
15) Good design is your best performance tuning tool - Good designs are easy to change and so easier to make faster. Good design involves having a way to measure application performance.
Ironically, although I wrote JAMon which is a performance tuning tool, very few programmers are less concerned with performance than I am. One of the reasons I created JAMon was because I saw many developers tuning code (and pointing fingers), that didn't need to be tuned. Experience has taught me that good performance follows good design, and bad code (and often bad performance) follows designs that emphasize performance.
16) If your page takes more than a couple seconds it probably needs tuning - Users aren't that patient and will move to another site or start mashing on the refresh button if your page is slow. Both outcomes won't be to your liking, but on the bright side - your competitors will be thrilled.
17) Your biggest scalability problem may be one user getting impatient and hitting refresh before the page returns - I have seen one user issue many many outstanding page requests, and so one user can single handedly bring your site down unless you build protection for this into your app from the start. (The JAMon servlet filter can detect this problem)
18) Don't return 10,000 rows - The bad news is browsers are slow in displaying so many rows. The good news is that your users really don't want to see so much data even if they say they do. It is your job as a developer to find out what they really want and give that capability to them.
19) Java is fast, very fast - Despite java's still lingering reputation of being slow - it is very fast. I can execute a method on my old clunker pc 60,000,000 times a second. Even object creation and garbage collection are quite fast.
20) www.javaperformancetuning.com - A great site with tons of good advice on java performance tuning. The site name says it all.
21) Google is your best friend - Google knows everything you want to know about performance tuning (and any other topic for that matter).
22) BasicTimingMonitor - If you don't use JAMon use this simple class.
23) Good articles to read to see how synchronization can affect performance (by Brian Goetz)
jdk 1.5 concurrency improvements - http://www-128.ibm.com/developerworks/java/library/j-jtp10264/
jdk 1.5 concurrency improvements to the collections - http://www-128.ibm.com/developerworks/library/j-jtp07233.html
24) Consider the ThreadLocal class as an easy way to make ANY stateful class thread safe, and it is easy to work with! - Here is a nice article on the topic again by Brian Goetz
25) A nice interview by Brian Goetz where he discusses many Java performance myths.
Here is the link to the full interview: http://java.sun.com/developer/technicalArticles/Interviews/goetz_qa.html
Here is Brian's home page with a list of all of his articles and a blog: http://www.briangoetz.com/
Here are some of the more important quotes from the interview:
26) Use Enterprise-Level Hardware - Fast software can't make up for slow hardware. Since a programmer's time is expensive and tweaking software for performance is tedious and error-prone, one of the more sensible investments an organization can make is real enterprise server hardware (multiple CPU's (NOT a multi-core CPU), large hard drives in a RAID configuration, gigabyte LAN, several gigabytes of RAM and so on). There's more than one organization that will take an old PC no one wants, put it in the cable closet and call it a "server". They will be the first to complain that Java is "slow".
The DeCapo? benchmark suite http://dacapobench.org/ is a useful tool for comparing the performance of Java platforms. It uses real-life applications (Eclipse, Tomcat, Geronimo, etc) to simulate real-life loads.
Once the server is up and running, monitor the hardware performance under realistic loads to spot bottlenecks (i.e. excessive swapping to disk is an indication more RAM is required). Use multiple servers and load balancing to alleviate overloading.
Don't use the same server for an application server and database. The database will take up huge portions of RAM to perform queries. The application server will be attempting to render the query results at the same time, competing with the database for RAM and CPU time. It is a bottleneck waiting to happen.
27) Think about CachingStrategies
28) Use visualvm and jconsole to monitor cpu, memory, garbage collection, object allocations, threads and more. jconsole comes with the jdk and visualvm is easy to download. Both are free and easy to use.