Showing posts with label Performance. Show all posts
Showing posts with label Performance. Show all posts

Monday, December 19, 2016

Use Debug Diag tool to debug and analyze problems

Microsoft’s “Debug Diag” tool is very helpful diagnostic tool that every developer should be aware of who works on Microsoft technologies -

Below are the benefits of “Debug Diag” tool
  1. App crash investigations
  2. Memory leak finding for .NET & COM components (i.e.e managed & unmanaged)
  3. Performance analysis of application

Provides two tools –
  1. Debug Collections – which capture data (dump file & text logs)
  2. Debug Analyzers – provides summary of analysis in the form of an HTML page. (Produces an MHT file that opens up in IE)

Additional information on “Debug Diag” tool from Microsoft that can be used for memory leak findings –
  1. Download link for ‘Debug Diag’ tool from Microsoft’s website.
    • Need to download “DebugDiagx64.msi” for 64 bit OS
  2. Link for blog on - How to create rules to capture “Memory Leak”
    • This article is written for old version, but concept is the same
  3. Link for blog on – Debugging Native memory leaks with Debug Diag
  4. Link for blog that describes – Additional options & analysis reports


Thursday, September 22, 2016

Avoid Boxing & Unboxing to improve performance

While writing code we generally don’t pay much attention to boxing & unboxing. It does matter in performance.

In relation to simple assignments, boxing and unboxing are computationally expensive processes. When a value type is boxed, a new object must be allocated and constructed. To a lesser degree, the cast required for unboxing is also expensive computationally.

  1. Boxed value type objects take up more memory
  2. Boxed value type objects require an additional read
  3. Short-lived value type objects eat up Gen 0 heap & this forces frequent garbage collections
  4. Boxing and unboxing operations consume CPU & time
  5. Casting is required & it can be costly


How to prevent boxing & unboxing:
  1. Use ToString method of numeric data types such as int, double, float etc.
  2. Use for loop to enumerate on value type arrays or lists (do not use foreach loop or LINQ queries)
  3. Use for loop to enumerate on characters of string (do not use foreach loop or LINQ queries)
  4. If you define your own value type then override implementation of basic object methods.
  5. Don’t assign value type instance to object unless unavoidable
  6. Use generic List<>, Dictionary<> (et al) instead of ArrList & HashTable.
  7. Use Nullable<> value types (examples int?, float? etc)
  8. When using string.Format (SrtingBuilder.AppendFormat) or similar API's that use 'params object[]' pass on value type objects by calling 'ToString()' method


Pay attention for below mentioned things & do some code refactoring
  1. Implicit boxing (Example: object num = 1; )
  2. Use of foreach on value types
  3. LINQ queries on value type collections
  4. Casting to value types

Friday, September 9, 2016

Using StringBuilder for Performance

High performance of application is implicit requirement, no one states it, and however it’s there and supposed to be taken care of. Here is my first blog on StringBuilder that hopefully help you.

Using StringBuilder is the most recommended way to concatenate large chunks of strings , mostly this happens in loop. It is the best approach to take, and despite this I have seen many developers not to follow this practice.
I have also seen developer’s instantiating StringBuilder in an inefficient ways too. Below are the guidelines for some efficient ways to use StringBuilder & get some performance.
  • Always try to instantiate StringBuilder with some default value or capacity
  • Use in large loops or at places where most of the concatenations are happening
  • Use the same instance of StringBuilder in all methods that construct a single string

Example code:

static void Main(string[] args)
{
    int guessLength = 30;
    StringBuilder sb = new StringBuilder(100 * guessLength); //Give capacity or value as far as possible
    for (int loop = 0; loop < 100; loop++)
    {
        sb.Append(loop).Append(":").AppendLine();
    }
    ConstructMessage(sb);
    ConstructAdditionalMessage(sb);
    Console.WriteLine(sb);
}

static void ConstructMessage(StringBuilder sb)
{
    for (int loop = 0; loop < 5; loop++)
    {
        sb.AppendFormat("{0}:{1}", loop.ToString(CultureInfo.InvariantCulture), Environment.NewLine);
    }

}
static void ConstructAdditionalMessage(StringBuilder sb)
{
    sb.AppendLine();
    for (int loop = 0; loop < 5; loop++)
    {
        sb.AppendFormat("{0}:{1}", loop.ToString(CultureInfo.InvariantCulture), Environment.NewLine);
    }
}


Can you guess why I have used “loop.ToString(CultureInfo.InvariantCulture)” in the above example code?

Related readings: