4.7 Performance Checklist

Most of these suggestions apply only after a bottleneck has been identified:

  • Establish whether you have a memory problem.

  • Reduce the number of temporary objects being used, especially in loops.

    • Avoid creating temporary objects within frequently called methods.

    • Presize collection objects.

    • Reuse objects where possible.

    • Empty collection objects before reusing them. (Do not shrink them unless they are very large.)

    • Use custom conversion methods for converting between data types (especially strings and streams) to reduce the number of temporary objects.

    • Define methods that accept reusable objects to be filled in with data, rather than methods that return objects holding that data. (Or you can return immutable objects.)

    • Canonicalize objects wherever possible. Compare canonicalized objects by identity.

    • Create only the number of objects a class logically needs (if that is a small number of objects).

    • Replace strings and other objects with integer constants. Compare these integers by identity.

    • Use primitive data types instead of objects as instance variables.

    • Avoid creating an object that is only for accessing a method.

    • Flatten objects to reduce the number of nested objects.

    • Preallocate storage for large collections of objects by mapping the instance variables into multiple arrays.

    • Use StringBuffer rather than the string concatenation operator (+).

    • Use methods that alter objects directly without making copies.

    • Create or use specific classes that handle primitive data types rather than wrapping the primitive data types.

  • Consider using a ThreadLocal to provide threaded access to singletons with state.

  • Use the final modifier on instance-variable definitions to create immutable internally accessible objects.

  • Use WeakReferences to hold elements in large canonical lookup tables. (Use SoftReferences for cache elements.)

  • Reduce object-creation bottlenecks by targeting the object-creation process.

    • Keep constructors simple and inheritance hierarchies shallow.

    • Avoid initializing instance variables more than once.

    • Use the clone( ) method to avoid calling any constructors.

    • Clone arrays if that makes their creation faster.

    • Create copies of simple arrays faster by initializing them; create copies of complex arrays faster by cloning them.

  • Eliminate object-creation bottlenecks by moving object creation to an alternative time.

    • Create objects early, when there is spare time in the application, and hold those objects until required.

    • Use lazy initialization when there are objects or variables that may never be used, or when you need to distribute the load of creating objects.

    • Use lazy initialization only when there is a defined merit in the design, or when identifying a bottleneck that is alleviated using lazy initialization.