Showing posts with label .NET tutorial. Show all posts
Showing posts with label .NET tutorial. Show all posts

01 July 2017

StringBuilder over string concatenation

Recently I was going through a code in my personal project written long back. The legacy code was using string concatenation to build a text in a loop which ran 75 iterations on average. In each loop, there were 4 string concatenations. So totally it was doing 300 string concatenations on one run. Long back I learned its better to use StringBuilder when 5 or move string concatenation is involved. So I wanted to see how StringBuilder helps with performance over string concatenation.

Code Performance is not just about execution time, it is just one metric among many important ones!

I did code execution time comparison using Stopwatch timer to build a same text using string concatenation and also by using StringBuilder class and I found NO time difference between the them at times. Even when there is an execution time difference it was negligible. Milliseconds difference over many iterations was not exciting!"

Then I realized "the time it took to complete a task, is just one metric to measure the performance of the code among many important other metrics, hence we also need to consider other metrics around .NET Memory Management i.e, Number of Generation 0 Collection, etc. So started to track the .NET CLR Memory Performance counters.

String concatenation and measuring .NET CLR Memory Performance counters

Let's consider below C# code sample. The code is building a text using string concatenation approach.

static void Main(string[] args)
      {
        for (int i = 0; i < 10000; i++)
        {
        string text = null;
        for (int j = 0; j < 600; j++)
        {
          text += string.Format("Name{0}{1}", Guid.NewGuid().ToString(), i.ToString());
        }
        Console.WriteLine(i.ToString());
        }
        Console.ReadLine();
     }

When above code completes all looping iterations and waiting for you to key in ENTER to exit, have a look the .NET memory counters for the underlying windows process. For this blog post, I used Process Explorer tool as it serves the purpose by providing All counters I am interested and also it is easy to use plus free.






















StringBuilder to build text and measuring .NET CLR Memory Performance counters

Let's consider the below C# code to build the text using StringBuilder.

static void Main(string[] args)
      {
        for (int i = 0; i < 10000; i++)
        {
         StringBuilder text = new StringBuilder();
        for (int j = 0; j < 600; j++)
        {
         text.AppendFormat("Name{0}{1}", Guid.NewGuid().ToString(), i.ToString());
        }
        Console.WriteLine(i.ToString());
        }
        Console.ReadLine();
     }

When the above code completes all looping iterations and waiting for you to key in ENTER key to exit, have a look at the .NET memory counters for the underlying windows process. For this blog post, I used Process Explorer tool as it serves the purpose by providing All counters I am interested, also it is easy to use and free!






















Test conclusion

If you look the at .NET CLR Memory Management metrics for the two cases, we can see there is a huge difference in 'Gen 0 Collection', 'Promoted memory from Gen 0' and '% time in GC' measurements.

The code which is using string concatenation to combine strings is resulting in 75809 Gen 0 Garbage collection compared to the code which is using StringBuilder just resulting in 730 Gen 0 Garbage collection. So there is roughly 99% gain of garbage collection performance by employing StringBuilder over String concatenation.

Test results indicate, the code which is using string concatenation is witnessing more memory allocation and Garbage collection compared to the code which is using StringBuilder to do the same unit of work.

With this post I would like to drive a point. Whenever you sit for design discussion, coding and code review, just don't consider the speed of execution as the single metric to lean towards an approach. Also consider other metrics like garbage collection, CPU utilization etc to arrive at a solution.

Important notes

  • The tests were ran on INTEL i7 dual core processor, 8 GB RAM and WINDOWS 10 Operating system machine which is light on resource consumption. Not many programs running.
  • Depending on the load, the performance counters value differs. So for any performance tests, you will always need to consider the NFRs to be supported. Consider benchmarking the performance considering the Non Functional Requirements(NFRs).

08 November 2012

constructors and destructors invocation sequence in inheritance

Sometime back I got a interview question, in inheritance class relationship, when you are trying to create a derived class instance which constructor will be invoked first?

Is it the base class constructor invoked first?

OR

Is it the derived class constructor invoked first?

Let's create a simple console application in C# language to demonstrate constructor invocation sequence/order:

namespace ConstructorInvocationSequenceExample
{
    class Program
    {
        static void Main(string[] args)
        {
            DerivedClass derivedClassObject = new DerivedClass();
            Console.ReadKey();
        }
    }
    public class BaseClass
    {
        public BaseClass()
        {
            Console.WriteLine("Base Class Constructor invoked.");
        }
    }
    public class DerivedClass : BaseClass
    {
        public DerivedClass()
        {
            Console.WriteLine("Derived Class Constructor invoked.");
        }
    }
}
Let's have a look at the C# sample code output below:

Base Class Constructor invoked.
Derived Class Constructor invoked.

After analyzing the example's output we can say:

Base class constructor is invoked first and then the derived class constructor.

It make sense because during a building in under a construction, first basement will be built then the the floors.

Let's create a plain console application example to demonstrate destructor invocation order:

namespace DestructorInvocationOrderExample
{
    class Program
    {
        static void Main(string[] args)
        {
            DerivedClass derivedClassObject = new DerivedClass();
            // Set the object to null and call 
            // the GC.Collect(), so that
            // destructors are invoked.
            derivedClassObject = null;
            GC.Collect();
            Console.ReadKey();
        }
    }
    public class BaseClass
    {
        ~BaseClass()
        {
            Console.WriteLine("Base Class Destructor invoked.");
        }
    }
    public class DerivedClass : BaseClass
    {
        ~DerivedClass()
        {
            Console.WriteLine("Derived Class Destructor invoked.");
        }
    }
}
Let's have look at the example output:

Derived Class Destructor invoked.
Base Class Destructor invoked.

After analyzing the example's output it is clear that:

Derived class destructor is invoked first and then the base class destructor.

It make sense because when building is being demolished, similar to Garbage collection - the floors will be demolished first and then the basement.