Performance And Memory Tips

Two things play a very significant role in any application development -- the application’s footprint and performance. Whenever I was asked to work on these two tracks, I used to visit a huge list of sites to get many more ideas apart from what I already knew.
So, I thought, why don’t I collate all the good points and add them to my repository? At the same time, I thought of sharing those points in this blog. Rather than making this blog post full of theory, I am planning to make it simple by just adding the bullet points.

Uh! Enough gossip. Let’s get started by going through some common and important rules.
  • Create object only when it is really required.

  • The more objects, the more poor the performance.

  • Grab resources, use them, and release at the earliest time.

  • The default capacity of StringBuilder is 16. So, if you want to store fewer than 16 values, then make sure to set the capacity.

  • Avoid unnecessary boxing and unboxing.

  • Prefer lazy loading.

  • Use Static variables cautiously as they will stay live throughout the application's life.

  • Avoid using IDisposable everywhere.

  • For web apps, enable Server GC.

  • Throw fever exceptions. Avoid using exceptions to control the program flow. Never catch exceptions that you cannot handle.

  • Use Performance Monitor to check the exception count and other relevant information.

  • Always implement the "Finally" block.

  • Prefer value types; i.e., If structure can work, then why take class?

  • Prefer AddRange() over Add() for adding multiple items to collection.

  • Trim your working set. Use and load the minimal and only the required number of assemblies. Prefer single huge assembly rather than using multiple small assemblies.

  • Prefer thread pool rather than creating a new thread for each request.

  • Use "For" loop for string iterations rather than "ForEach" iterator.

  • Use StringBuilder for string manipulation.

  • Prefer early binding.

  • Be careful while choosing .NET collections as each collection is designed for specific purpose.

  • Use StringCollection class to store strings.

  • Use Hashtable when frequent query is required on large number of records.

  • Prefer ListDictionary as it is faster than HashTable for <10 records.

  • For small data, go for SortedList. For large data, go for ArrayList and then call Sort method on it.

  • Prefer arrays over collections unless you need some special functionality as they use contiguous memory arrangement and are faster.

  • Avoid calling GC.Collect method because it traverses all the generations. If you have to call GC.Collect in your particular niche case, then make sure to clean finalized object also using GC.WaitForPendingFinalizers() and again call GC.Collect. This will collect all the dead objects.

  • Avoid implementing "Finalize" as it requires 2 GC cycle. Implement it only when you hold unmanaged resources.

  • Call GC.SuppressFinalize method inside Dispose method.

  • Be cautious while using Thread.Suspend, as it may lead to deadlock due to incorrect synchronization.

  • Lock(object) is the cheapest method to perform synchronization.

  • Avoid locking ‘this’ as it will lock the entire object. Even a few of its members don’t require synchronization.

  • Prefer Using statement to ensure that Dispose is called.

  • A very good diagram is given on MSDN which talks about a few more concepts around this area.
Hope, you enjoyed reading this blog. Please drop your valuable comments, so that I can improve this list further.
Happy learning!!!