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.