There are two basic inter-related performance measures: team performance and software performance. The two aspects are the Yin & Yang of performance and it’s extremely difficult to have one without the other. Variables involved in team performance are team dynamics, resources made available to the team as well as the degree of that availability, and constraints enthralled upon them. Here are some ideas:
Raise team performance
- Improve team dynamics
- Have regular team socials and bonding events
- Invite team building professionals to speak with the team and propose new ideas
- Limit overtime work to the extent possible
- Make resources easily available to the team
- Keep an open door to and from management
- Make it easy for the team to perform
- Cleanse data
- Data should be cleaned up where it resides, it’s the least expensive long term option
- Logic should not cleanup data, it may appear to be the least expensive option at any given moment but when taken into account the efforts involved in adding the additional logic times the distribution of that logic to various parts of one or more applications and resolving any associated bugs, it’s likely to be far more expensive. Different types of data cleanup would be required at different logic points cluttering business logic and multiplying maintenance effort. Moreover, this would shadow and further perpetuate the dirty data problem, thereby, compounding the problem and the costs
- Encourage design before code approach and hold design sessions
- Amount of test required is inversely proportional to the quality of the design
- Degree of database normalization is proportional to maintainability and inversely proportional to performance
- Pros and cons that apply to database normalization, apply to code normalization as well
- Promote writing routines based on need on hand and not on potential need. Although a small percentage of potential need materializes, it’s overall a waste of time
Lower CPU Cycles
- Implement caching and pooling
- Cache application specific data, e.g., code tables, configurations, etc. on the UI or the middle-tier
- Cache user specific data in session, only if loading it is expensive
- Pool expensive and/or heavily used resources, e.g., threads, database connections, singleton classes, etc.
- Override Object.Equal() in value types. If this method is not overridden any call to it will result in the value type being boxed first because Object is a reference type
- Use for (int i=0; i<obj.count; i++) instead of foreach (string s in obj.values), unless boxing/unboxing is involved
- Use typed collections and generic types instead of object types
- Provide setter methods for setting multiple properties simultaneously. This avoids multiple round trips, potentially crossing process boundaries with each trip. Note that you should still call the actual setters from within the method to maintain business and other rules
- Seal classes and methods where possible. Makes methods candidates for in-lining, improving performance
- Exit the routine at the earliest possible time, don’t wait to finsih the loop, complete waste of CPU cycles
- Use !Page.IsPostBack in every page & user control load event unless otherwise necessary
- Use StringBuilder for string manipulation. String type is immutable and every mutating operation results in a new copy of the object
- Terminate page execution unless necessary, Response.Redirect("http://www.microsoft.com", true);. The runtime 2.0 no longer generates the resultant exception, so, don’t have to handle it
- Avoid unnecessary public members. There are serialization overheads that may come into play, if serialization is involved (e.g., using state server, etc.). Serialization may be turned off for individual members but they are generally on by default
- Pass by reference, passing by value will generally be slower than passing by reference, because, at least one copy needs to be made to pass by value
- Avoid using arrays in parameters. Provide explicit overloads, if possible, the IL generates those overloads anyway if arrays are used as parameters
- Avoid using the volatile keyword. It forces reads from memory instead of register. There are generally better multithreading techniques
Lower memory footprint
- Avoid using session, because it raises server memory footprint raising memory constraints and hence potential for paging
- Minimize use of session to communicate between pages. It can lead to memory leaks and comprehensive cleanup effort. Session must be cleansed, otherwise horizontal scalability is adversely affected
Manage expectation
- Streamline UI load. Only load what needs to be there immediately. Load the rest either on demand or asynchronously on a background thread
- Don’t run long running queries on user’s behalf to be helpful, especially on control load