|
In general, when faced with an expensive computation,the first question is not How can it speed up this computation?, but rather Can I modify design to get rid of this computation altogether? It is better to avoid a difficult situation in the first place rather than to find a clever way to get out. The same applies to object creation and garbage collection. It is preferred to restrict the proliferation of objects in Java code rather than to rely on the latest and greatest improvements in the garbage-collection subsystem. One way to limit the creation of new objects is to recycle old ones. Suppose you have a servlet that uses a Vector object in its response generation. Since a servlet is intended to serve repeated requests in its lifetime, you must decide what to do with this Vector object as it goes from one request to the next. You have a couple options: One, you could create a new Vector object for every request. Old Vector objects used by earlier requests are going to be garbage collected at some later point. The second option is to make it a member of the servlet object and recycle it from one invocation to the next. At the end of one request you reset the Vector member and reuse it for the next request. Of course, reseting an object often replicates much of the constructor code, but it avoids memory allocation and therefore should always be faster than new object construction. Consequently, recycling an object is the preferred way to go. It is faster and it reduces the memory footprint, a double bonus. Reduction in memory footprint could help application speed by increasing the effectiveness of the processor cache. To quantify the performance win, we tested one million iterations of a loop in which a new Vector object was created every time: String s = "HelloWorld"; String p = null; long start = System.currentTimeMillis(); // <+++ Start timing for (int i = 0; i < n; i++) { Vector v = new Vector(); v.addElement(s); v.addElement(s); v.addElement(s); p = (String) v.elementAt(0); } long stop = System.currentTimeMillis(); // <+++ Stop timing We compared it to a second version that recycles the same Vector object from one iteration to the next: Vector v = new Vector(); long start = System.currentTimeMillis(); // <+++ Start timing for (int i = 0; i < n; i++) { v.clear(); // Reset the Vector to an initial state v.addElement(s); v.addElement(s); v.addElement(s); p = (String) v.elementAt(0); } long stop = System.currentTimeMillis(); // <+++ Stop timing Recycling the Vector object between iterations was faster than creating a new one every time
|