If you haven’t gone through my previous article on generics then please go through it here.
In my previous article, we discussed about the type safety and code re-usability feature of generics, continuing on that, in this article we will discuss about the performance improvement generics brings in to our code.
How usage of generics improves performance ?
Generics can bring performance improvement in terms of speed and memory consumption as follows.
- With generics in our program, we don’t need to use type casting, that eliminates the extra work compiler does to check the type at run-time. This certainly improves the performance of the application.
- Another benefits generics bring is that, it eliminates the possibility of boxing and un-boxing in most of the situations, which generally improves the performance and reduces the memory consumption.
Lets take an example of non generic type :
In below example, we are using a non generic type ArrayList to hold some object variables and then evaluating the time spent to read the data from the ArrayList.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
using System; using System.Collections; using System.Diagnostics; using System.Text; namespace GenericsPerformanceSample { class Program { static void Main(string[] args) { PrintDataNonGeneric(); Console.Read(); } public static void PrintDataNonGeneric() { int x = 10000; StringBuilder sb = new StringBuilder(); // ArrayList is not type-safe, it stores object references. ArrayList nonGenArrayList = new ArrayList(); // Add a bunch of random strings to the array list. for (int i = 0; i < x; ++i) { nonGenArrayList.Add(Guid.NewGuid()); } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); foreach (object gui in nonGenArrayList) { //Append the string in the array list to the string builder sb.Append(gui); } stopwatch.Stop(); TimeSpan ts = stopwatch.Elapsed; Console.WriteLine("Time spent - With out Generics: {0} milliseconds", ts.TotalMilliseconds.ToString()); } } } |

Output :
When the above code executes, then the compiler takes around 3.1544 millisecond to read the data from the non generic ArrayList and append in to the string builder object.
Lets take an example of generic type :
In below example, we are using a generic type List<string> to hold a string variable and evaluating the time spent to read the data from the List<string>.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
using System; using System.Collections.Generic; using System.Diagnostics; using System.Text; namespace GenericsPerformanceSample { class Program { static void Main(string[] args) { PrintDataGeneric(); Console.Read(); } public static void PrintDataGeneric() { int x = 10000; StringBuilder sb = new StringBuilder(); // List<string> is of generic type, it only allows string type. List<string> list = new List<string>(); // Add a bunch of random strings to the generic List<string> . for (int i = 0; i < x; ++i) { list.Add(Guid.NewGuid().ToString()); } Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); foreach (string gui in list) { //Append the string in the generic list to the string builder sb.Append(gui); } stopwatch.Stop(); TimeSpan ts = stopwatch.Elapsed; Console.WriteLine("Time spent - With Generics:{0} milliseconds", ts.TotalMilliseconds.ToString()); } } } |

Output:
When above code executes, then the compiler takes around 0.9073 millisecond to read the data from the generic List<string> and appends in to the string builder object.
If you look at both output, then generic type is the clear winner. It takes less time to execute comparatively to non generic type. So the question arises, Why the compiler took more time while dealing non generic types ?
- If you look at the non-generic example closely then here what happens. In the code nonGenArrayList.Add(Guid.NewGuid()); , the compiler perform a casting operation to convert Guid.NewGuid(); to object.
- Again, when it hit the line foreach (string gui in list) , then compiler performs a casting operation to convert from object to string. This extra work that compiler performs makes it slower.
- However, in the generic example, there is no overhead of type casting during run time, since there is already compile time type check has performed, thus makes it faster.
I hope this article gave you some idea about the basics of generics and its usage. We will deep dive more in to generics in upcoming days, keep visiting to the site and also drop your invaluable feedback’s.
You might want to update your code samples relating to performance. The first code sample demonstrating the non-generic type has a for loop set at 10,000. The second example demonstrating a generic type has a loop set at only 1,000.
Thanks Steven for the feedback 🙂 I will have a look and correct that.