13.8 Performance Checklist

  • Consider performance at each stage of the development cycle. Create a performance plan that anticipates all the various performance issues that regularly crop up.

    • Plan for tuning phases.

    • Leave code tuning until after the code is functional and debugged.

    • Consider how a particular performance change will affect other parts of the application.

    • Identify performance limitations.

    • Eliminate performance conflicts.

    • Consider how the performance scales as the application scales.

    • Consider how the performance scales as the application load varies.

  • Determine the general characteristics of the application in the analysis and design phases.

    • Minimize the features in the requirements.

    • Specify performance boundaries and goals.

    • Consider the numbers, sizes, and sources of objects, data, and other parameters of the application.

    • Create an abstract model of the application to identify any performance problems.

    • Design applets to engage the user as soon as possible.

    • Identify and focus on the performance costs of shared resources.

    • Target decoupling, indirection, abstraction, and extra layers in the design.

    • Predict the performance of design elements that block, copy, queue, or distribute.

    • Consider alternative designs that bypass or reduce high-performance costs.

    • Avoid transactions where possible.

    • Minimize transaction time where transactions are necessary.

    • Lock only where the design absolutely requires it.

    • Design parallelism into the application wherever possible. Identify what cannot be parallelized.

    • Watch out for too much parallelism. There are diminishing returns from parallelism overhead.

    • Balance workloads. Unbalanced parallel activities may limit the performance of the system.

    • Split up the data among many different files (preferably on separate disks).

    • Support asynchronous communications.

    • Decouple activities so that no activity is unnecessarily blocked by another activity.

    • Minimize points where parallel activities are forced to converge.

    • Design for redundant servers and automatic switching capabilities.

    • Consider using batch processing.

    • Design more flexible method entry points to your classes to provide greater performance flexibility when developing reusable code.

  • Partition distributed applications according to the data and processing power of components.

    • Minimize the communication between distributed components.

    • Avoid generating distributed garbage.

    • Reduce transfer costs by duplicating data.

    • Cache distributed data wherever possible.

    • Minimize the synchronization requirements of duplicated data.

    • Use compression to reduce transfer time.

  • Design objects so that they can be easily replaced by a faster implementation.

    • Use interfaces and interface-like patterns (e.g., the factory pattern).

    • Design for reusable objects.

    • Use stateless objects.

    • Consider whether to optimize objects for update or for access.

    • Minimize data conversions.

    • Minimize the number and size of developed classes for applications that need to minimize download time.

  • Constantly monitor the running application.

    • Retain performance logs. Choose one set as your comparison standard.

    • Monitor as many parameters as possible throughout the system.

    • Note every single change to the system. Changes are the most likely cause of performance variations.

    • Listen to the application users, but double-check any reported problems.

    • Ensure that caching effects do not skew the measurements of a reported problem.

  • Make the user interface seem fast.

  • Train users to use the application efficiently.

  • Minimize server-maintenance downtime.

  • Implement a performance plan as an integral part of application design and development.