Java Performance Tuning
Java(TM) - see bottom of page
Our valued sponsors who help make this site possible
JProfiler: Get rid of your performance problems and memory leaks!
Newsletter no. 1, December 20th, 2000
Get rid of your performance problems and memory leaks!
Get rid of your performance problems and memory leaks!
There's been a nice crop of recently published performance related
These all have their tips listed below. In addition, I've extracted
the tips from a number of other older performance related web pages.
These include a nice Java structures page, several pages on object
pooling, a few basic animation tutorial tips, and others. All pages
are listed below in the Tips section, and have
been added to the Tuning Tips page .
Sun are having a community chat session with Thomas Christopher
and George Thiruvathukal, the authors of "Threading and Concurrency
in the Java Platform". I haven't had a chance to read the book
yet, but the blurb looks good. In any case, this is a chance
for you to run any performance problems past a couple of experts
for free. The chat is scheduled for Jan. 9 at 11:00 A.M. PST.
Other additions to the website
In addition to the new tips, some further resources have been added
to the resource page (listed below). These
resources have mainly been performance related books, not specifically
Java ones, and I've also started a new section listing Java
performance discussion groups. The Javaranch discussion group had
quite a flurry of messages in November due to some copies of my book
being given away there.
A high level overview of technical performance tuning, covering 5 levels of tuning competence. Note that this is a reissue of an article already available from my book's examples page at O'Reilly (Page last updated November 2000, Added 2000-12-20, Author Jack Shirazi). Tips:
- Start tuning by examining the application architecture for potential bottlenecks.
- Architecture bottlenecks are often easy to spot: they are the connecting lines on the diagrams; the single threaded components; the components with many connecting lines attached; etc.
- Ensure that application performance is measureable for the given performance targets.
- Ensure that there is a test environment which represents the running system. This test-bed should support testing the application at different loads, including a low load and a fully scaled load representing maximum expected usage.
- After targetting design and architecture, the biggest bang for your buck in terms of improving performance is choosing a better VM, and then choosing a better compiler.
- Start code tuning with proof of concept bottleneck removal: this consists of using profilers to identify bottlenecks, then making simplified changes which may only improve the performance at the bottleneck for a specialized set of activities, and proceeding to the next bottleneck. After tuning competence is gained, move to full tuning.
- Multi-user performance tests can typically take a full day to run and analyse. Even simple multi-user performance tuning can take several weeks.
- After the easily idenitified bottlenecks have been removed, the remaining performance improvements often come mainly from targetting loops, structures and algorithms.
- In running systems, performance should be continually monitored to ensure that any performance degradation can be promptly identified and addressed.
Article about optimizing queries on Maps. (Page last updated November 2000, Added 2000-12-20, Author Jack Shirazi). Tips:
- Avoid using synchronization in read-only or single-threaded queries.
- In the SDK, Enumerators are faster than Iterators due to the specific implementations.
- Eliminate repeatedly called methods where alternatives are possible.
- Iterator.hasNext() and Enumerator.hasMoreElements() do not need to be repeatedly called when the size of the collection is known. Use collection.size() and a loop counter instead.
- Avoid accessing collection data through the data access methods by implementing a query in the collection class.
- Elminate repeated casts by casting once and holding the cast item in a correctly typed variable.
- Reimplement the collection class to specialize for the data being held in the collection.
- Reimplment the Map class to use a hash function which is more efficient for the data being mapped.
Efficiently formatting doubles (Page last updated December 2000, Added 2000-12-20, Author Jack Shirazi). Tips:
- Double.toString(double) is slow. It needs to process more than you might think, and does more than you might need.
- Proprietary conversion algorithms can be significantly faster. One such algorithm is presented in the article.
- Converting integers to strings can also be faster than the SDK. An algorithm successively stripping off the highest is used in the article.
- Formatting numbers using java.text.DecimalFormat is always slower than Double.toString(double), because it first calls Double.toString(double) then parses and converts the result.
- Formatting using a proprietary conversion algorithm can be faster than any of the methods discussed so far, if the number of digits being printed is not large. The actual time taken depends on the number of digits being printed.
Article about optimizing I/O performance. (Page last updated November 2000, Added 2000-12-20, Author Brian Goetz). Tips:
- Measure early, measure often. You can't effectively manage performance if you don't know the source of your problem.
- Spending days tuning a subsystem that accounts for 1 percent of an application's total runtime simply cannot yield more than a 1 percent improvement in application performance.
- Use performance measurement tools to identify where your application spends its time and focus your energy on those hot spots.
- Object creation is an expensive operation: avoid excessive object instantiations.
- Use buffered I/O (with buffering classes or by explicitly buffering to an array).
- InputStream runs faster than Reader.
- Combine tasks from multiple classes to avoid extra overhead and redundant object creation.
Basic article on performance tuning techniques. (Page last updated January 2001, Added 2000-12-14, Author Tarak Modi). Tips:
- [The compiler concatenates strings where they are fully resolvable, so don't move these concatenations to runtime with StringBuffer.]
- Where the compiler cannot resolve concatenated strings at compile time, the code should be converted to StringBuffer appends, and the StringBuffer should be appropriately sized rather than using the default size.
- Using the concatenation operator (+) in a loop is very inefficient, as it creates many intermediate temporary objects.
- Presizing collections (like Vector) to the expected size is more efficient than using the default size and letting the collection grow.
- Removing elements from a Vector will necessitate copying within the Vector if the element is removed from anywhere other than the end of the collection.
- Cache the size of the collection in a local variable to use in a loop instead of repeatedly calling collection.size().
- Unsynchronized methods are faster than synchronized ones.
- [Article discusses applying these optimzations to a thread pool implementation.]
Particle's pretty good coverage of the main Java data structures. Only a few tuning tips: reuse, pools, optimized sorting. But knowing which structure to use for a particular problem is an important performance tuning technique. (Page last updated April 2000, Added 2000-12-20, Author J. Particle). Tips:
- Make linked lists faster by having dummy first and last nodes.
- Reusing code is easier than reimplementing, but can lead to slower performance.
- Use node pools to reduce memory impact.
- Sorting elements on insertion means they don't need to be sorted later.
- [Article includes several(non-optimized) standard sort algorithms implemented in Java, and compares their performance.]
- [Article discusses optimizing a quicksort.]
- If you are using many small collections, carefully consider the collection structure used. Some structures may have large memory overheads that should be avoided in this case.
- Some discussion of hidden surface removal for graphics.
Various performance tips from a JavaOne 1998 presentation. (Page last updated September 1998, Added 2000-12-20, Author Tony Squier & Steven Meloan). Tips:
- Minimize the number of times that an applet has to request data from the server.
- Package Applet images into a single class file.
- Use Thread pools where these improve performance.
- Use BufferedIO streams to access URLConnection's Input/Output streams.
Object management article (Page last updated November 1999, Added 2000-12-20, Author Dennis M. Sosnoski). Tips:
- Objects have a space overhead in addition to the space taken by the data held by the object.
- Object creation and garbage collection have significant overheads.
- Providing you're sensible about creating objects in heavily used code, it's easy to avoid the object churn cycle.
- The easiest way to reduce object creation in your programs is by using primitive types in place of objects.
- Avoid using wrapper classes (for primitive data types, e.g. Integer) as they impose extra overheads.
- Avoid convenience classes like Point if you can manage the underlying data directly.
- Reuse objects where possible.
- Use object pools where this is helpful in reusing objects, but be careful that the pool implementation does actually give a performance improvement (dedicated pools within the class can be significantly faster than abstract pool implementations).
- Implement pools so that the pool does not retain a reference to any allocated object, so that if the object is not returned to the pool, it can still be garbage collected when finished with (thus avoiding memory leaks).
Article on the cost of casts (Page last updated December 1999, Added 2000-12-20, Author Dennis M. Sosnoski). Tips:
- Casting can be detrimental to performance.
- Improve performance by minimizing casting in heavily used code.
- Some casts take nearly as long as a simple object allocation.
- [Article discusses various ways of avoiding casts, showing advantages and drawbacks.]
Article on Java 2 collections (Page last updated February 2000, Added 2000-12-20, Author Dennis M. Sosnoski). Tips:
- Convert collections into arrays for improved access speed.
- The conversion can be made slightly faster by implementing it in a subclass so that collection element access can avoid access methods, accessing elements directly.
- Customized implementations of Hashtables can perform better.
- Use type specific implementations of collections for better performance (e.g. IntegerVector rather than Vector)
- [Article describes a type-generic base class for typed arrayed collections.]
Article on building an object pool for improved performance. (Page last updated June 1998, Added 2000-12-20, Author Thomas E. Davis). Tips:
- [Article discusses generic pool issues including storage, tracking, and expiration times of pool elements.]
- Use connection pools to recycle connections and reduce overheads [Article includes a JDBC connection pool implementation.]
Article on improving object pools performance. (Page last updated September 1998, Added 2000-12-20, Author Thomas E. Davis). Tips:
- Use an expiration thread to clean up excessive amounts of objects in the pool.
- Use java.lanf.ref.Reference objects to determine when objects checked out but never checkd in have been released by the application.
- Limiting the size of the pool can adversely impact performance.
Article on recycling resource pools (Page last updated 1998, Added 2000-12-20, Authors Philip Bishop and Nigel Warren). Tips:
- Check for broken resources when putting them back in the pool.
- Use the builder pattern: break the construction of complex objects into a series simpler Builder objects, and a Director object which combines the Builders to form the complex object. Then you can use Recycler (a type of Director) to replace only the broken parts of the complex object, so reducing the amount of objects that need to be recreated.
Animation in java applets article. Old article, but basically sound (the basics haven't changed). (Page last updated March 1996, Added 2000-12-20, Authors Arthur van Hoff and Kathy Walrath). Tips:
- Use a separate thread to draw the animation. Do not use the paint() method.
- Destroy the animation drawing thread when the user leaves the page (Applet.stop() is called) to avoid consuming CPU when nothing is being viewed.
- Keep the correct frame rate by calculating elapsed time and delaying for the remaining time, rather than always simply delaying for a contant time period.
- Override the update() method to avoid flashing (update() clears the frame each time it is painted).
- Use double buffering to eliminate further flashing and usually faster drawing: drawing offscreen is potentially faster, and mapping blocks of pixels oto the screen is normally very fast.
- Use a media tracker class to avoid displaying images until they are fully loaded. [This still applies, but Java 2 has more interfaces to help you do this.]
- Use image strips to load multiple images in one action.
- Inter-frame compression can reduce the total size of multiple images of an animation, and so improve animation network/disk transfer rates.
Another tutorial from Sun. This ones on animation (Page last updated ?, Added 2000-12-20, Author ?). Tips:
- Normal frame rates for animation: 8 frames per second (fps) for poor quality animation; 12 fps for standard animation; 24 fps for short bursts of smooth, realistic motion.
- Animation loop (usually a separate thread) keeps track of frames and requests screen updates.
- Suspend the animation whenever it is not visible.
- Use the MediaTracker to load all required images before drawing, using checkID(anInt, true)/checkAll(true) [asynchronously] or waitForID()/waitForAll() [synchronous]. [example code included in article]
- Combine images in a single file (e.g. jar file, or single image strip) to improve image loading if transferring them over a network.
Basic animation tutorial (Page last updated ?, Added 2000-12-20, Author Dave ?). Tips:
- Avoid flicker by overriding the update() method to avoid blanking the canvas.
- Use a separate thread to manage the calculations and drawing.
- Use MediaTracker to load all required images before drawing.
- Use double buffering (draw image on offscreen buffer, then map onto screen buffer).
- Use synchronization to synchronize methods in the two threads.
The Colt distribution: A set of open source libraries for High Performance Scientific and Technical Computing in Java. Contains efficient and usable data structures and algorithms competitive or superior to other toolkits.
Article describing Adrian Cockroft's Metrognome class and GPercollator tool (Page last updated October 1997).
Java Pitfalls: Time-Saving Solutions and Workarounds to Improve Programs by Michael C. Daconta (Editor), Eric Monk, J. Paul Keller, Bohnenberger, Keith Bohnenberger.
Algorithms in Java, Parts 1-4 : Fundamentals, Data Structures, Sorting, Searching by Robert Sedgewick, Tim Lindholm. Due January 2001 (or later, may be delayed).
Data Structures & Algorithms in Java by Mitchell Waite, Robert Lafore. (Waite Group Press)
Data Structures and Algorithm Analysis in Java by M. Weiss.
Writing Efficient Programs by Jon Louis Bentley (Prentice Hall, 1982). (out of print).
The Art of Computer Programming, Volumes 1-3 by Donald E. Knuth (Addison-Wesley).
Performance Engineering of Software Systems by Connie Smith (Addison-Wesley, 1990).
High Performance Client/Server by Chris Loosley & Frank Douglas (John Wiley & Sons).
System Performance Tuning by Mike Loukides, (O?Reilly & Associates).
Windows NT Performance Monitoring, Benchmarking, and Tuning by Mark T. Edmead & Paul Hinsberg, (New Riders).
Windows NT Applications: Measuring and Optimizing performance by Paul Hinsberg, MacMillan (Technical Publishing).
Web Performance Tuning by Patrick Killelea, (O?Reilly & Associates).
The Java Ranch has a number of Java discussion forums, including one devoted to performance with some interesting discussions.
The Server Side has a number of Java server-side (EJB etc) focussed discussion forums, including one devoted to performance with some interesting discussions.
Last Updated: 2017-10-01
Copyright © 2000-2017 Fasterj.com. All Rights Reserved.
All trademarks and registered trademarks appearing on JavaPerformanceTuning.com are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries. JavaPerformanceTuning.com is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
RSS Feed: http://www.JavaPerformanceTuning.com/newsletters.rss
Trouble with this page? Please contact us