"More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason-including blind stupidity."Before we can discuss how to improve performance, it's necessary to define what performance is. This isn't as simple as it sounds-people often mean very different things when they talk about performance. There are several aspects of performance, each of which contribute to the overall performance of an application.
Computers fascinate people with their ability to carry out tasks with blinding speed. When a computer, for whatever reason, doesn't perform a task quickly, users are disappointed. Developers often use the terms "speed" and "performance" interchangeably. However, to understand the different types of problems that can be encountered, all of the different aspects of performance must be considered:
These factors lay the foundation for a better understanding of the performance landscape. Some aspects of performance are primarily applicable to client-side systems, some to server-side systems, and some to both. Understanding how each factor can contribute to the performance characteristics of a system will help you analyze the performance of your own applications.
Much of the software performance literature centers on computational performance. Obviously, which algorithms you use and how you implement them are key factors in the overall performance of your software-Chapter 8 focuses on the selection and use of algorithms and data structures. It turns out, however, that this is only part of the performance picture. You need to consider factors beyond computational performance if you want to produce truly high-performance software.
It's not uncommon for a system to perform well while under development, but perform very poorly once deployed. Because software developers typically have considerably more physical memory in their workstations than average users, a program that runs comfortably on a developer's machine might require more memory than is available when installed on a user's machine. If your software is going to be deployed on machines with limited RAM resources, you need to design your software with the target configuration in mind.
It's also important to remember that your program probably won't be the only one running on a user's machine-users typically keep two or three applications running at a time. If your program consumes all of their memory resources, your users aren't going to be very happy.
If you're like most developers, you probably have an intuitive understanding of the issues regarding memory usage, but you might not know how to accurately measure or optimize your software's RAM footprint. Two tactics chapters focus on footprint issues-Chapter 5, RAM Footprint, and Chapter 6, Controlling Class Loading.
Historically, systems based on Java technology have been slow to launch. If you're developing a client application, you need to watch out for this problem. Specific tactics for minimizing startup time are discussed in Chapter 6, Controlling Class Loading, and in Chapter 12, Deployment.
It's also possible for an application to run slower when it's first started than it does after it has been running for a while. More advanced Java runtime systems, such as the Java Hotspot virtual machine (HotSpot VM), gradually compile more and more of a program's code as they run. The speed of the application ramps up as more of the code is compiled, as shown in Figure 1-1.
In server environments, this behavior might not be a problem, but it can be a major issue for client-side systems. You should be aware that it can affect the performance of your application, particularly if it will be deployed on the client.
Appendix A provides additional information about how the HotSpot VM affects performance.
Performance improves as more code is compiled
Figure 1-2 shows a theoretical system that isn't scaling well. As the number of users on the system increases, the average response time increases exponentially. This system will eventually reach a point where each user waits for an unacceptable amount of time.
In contrast, Figure 1-3 shows a system that scales in a more desirable manner. Although the average response time does increase as more users log on to the system, the response time degrades gradually.
Note that both of these systems show the same performance characteristics for small numbers of users (up to 250). It is only with larger numbers of users that the systems start to show their true characteristics. It's important to measure a system's performance under a load comparable to that which it needs to support when it's deployed.
The design decisions you make can determine whether your system will scale well or break down when heavily stressed in real-world situations. While scalability is often associated with servers, it can be just as important for client applications. For example, consider a word processor. It might work well when the user is editing a five-page letter, but how about a 200-page book? Can it handle it, or does typing slow to a crawl as the program tries to lay out the entire document each time the user presses a key?
A system that doesn't scale well
A system that scales well
It's important to be aware of potential scalability issues and design your software to accommodate its intended usage. Many techniques for ensuring that a program scales well are problem-domain specific. However, there are a number of general guidelines that can help you. Some of these are described in Section 2.1.2, Object-Oriented Design. Chapter 10, Swing Models and Renderers, contains information about developing scalable GUIs.
It turns out that there are many ways to improve how fast an application feels to the user without actually making any of the code run faster. These range from simple things like changing the mouse cursor to a wait cursor while your application is busy, to performing complex processing with multiple background threads. It's possible to make an interface feel responsive, even when the program is waiting for data from a slow network. You'll find several examples of how to improve perceived performance in Chapter 11, Writing Responsive User Interfaces with Swing.