|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Justified or not, Java is sometimes perceived as slow. Compared with other languages—such as C++—that are compiled into machine code, Java is interpreted at runtime; and all other things being equal, compiled machine code is faster than interpreted byte code. Of course, you might argue that Java can hold its own, mainly due to advanced technologies such as just-in-time (JIT) compilers and Java HotSpot, and you'd be mostly correct. Today's JVMs are modern marvels that wring amazing performance out of Java byte code.
Regardless of modern JVM efficiency, you should always look for programming techniques that boost performance. In this installment of Java Design Patterns, I discuss one of those techniques that, not surprisingly, takes the form of a design pattern: the Flyweight pattern. Let's see how it works.
Note: You can download this article's source code from Resources.
Object-oriented design is sometimes at odds with performance. From a design standpoint, it's best to encapsulate everything in an object so you can treat those objects uniformly, reuse them, and extend them. Unfortunately, modeling everything as an object can be expensive performance-wise. A case-in-point is Smalltalk, which literally models everything as an object, as opposed to Java, which provides a mix of objects and intrinsic types. Today, Java is much more prevalent than Smalltalk, due in no small part to Java's better performance.
Note: Java also provides static type checking, which Smalltalk lacks. Although static type checking is widely regarded as beneficial, most Smalltalk developers argue against it.
Even though Java provides a mix of objects and intrinsic types, Java applications can create a huge number of objects. For example, trees can have an unlimited number of rows, so if you model each row as a distinct Swing component, you're asking for trouble. For fine-grained objects such as tree nodes, you can implement the Flyweight pattern to create a small pool of shared objects, which significantly reduces the number of objects created. Soon enough, you'll learn how to implement flyweights and share them; in the meantime, it's sufficient to understand that flyweights are shared objects and that using them can result in substantial performance gains.
In Design Patterns, the Gang of Four (GOF) authors describe the Flyweight pattern like this:
Use sharing to support large numbers of fine-grained objects efficiently.
Figure 1 shows a class diagram for the Flyweight design pattern.
Figure 1. Flyweight class diagram
Flyweights are typically instantiated by a flyweight factory that creates a limited number of flyweights and doles them out, one at a time, to clients. Those flyweights are instantiated according to some criteria. For example, you might have a pool of line objects that know how to draw lines. In that case, the flyweight factory could create one line object for each line color, such as one object for white lines and another for blue lines. Those lines, which are flyweights, get reused whenever you draw white or blue lines. If you have a drawing with 1,000 white lines and 6,000 blue lines, only two lines—instead of 7,000—are actually instantiated.
Archived Discussions (Read only)