C# Implicitly Typed Local Variables Internals

OK, so most .NET coders are aware that C# >= 3.0 offers the ‘var’ keyword to provide implicitly typed local variables. One thing that intrigues me is just how this is achieved, and is their there any performance loss/gain by choosing this method ?

Take for instance the following small C# program:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

public class nongeneric_class
{
public object Data { get; set; }
}

public class generic_class
{
public T Data { get; set; }
}

public class main
{
public static void Main(string[] args)
{
const int ITERATION_COUNT = 10000000;
Stopwatch stopwatch;

// Generic Class With No Dynamic Variable
stopwatch = Stopwatch.StartNew();

for (int i = 0; i < ITERATION_COUNT; i++)
{
generic_class gc = new generic_class();
gc.Data = i;
int data = gc.Data;
}

Console.WriteLine("Generic Class With No Dynamic Variable: {0}ms", stopwatch.ElapsedMilliseconds);

// Generic Class With Dynamic Variable
stopwatch = Stopwatch.StartNew();

for (int i = 0; i < ITERATION_COUNT; i++)
{
var var_gc = new generic_class();
var_gc.Data = i;
int data = var_gc.Data;
}

Console.WriteLine("Generic Class With Dynamic Variable: {0}ms", stopwatch.ElapsedMilliseconds);

// Non-Generic Class With No Dynamic Variable
stopwatch = Stopwatch.StartNew();

for (int i = 0; i < ITERATION_COUNT; i++)
{
nongeneric_class ngc = new nongeneric_class();
ngc.Data = i;
int data = (int)ngc.Data;
}

Console.WriteLine("Non-Generic Class With No Dynamic Variable: {0}ms", stopwatch.ElapsedMilliseconds);

// Non-Generic Class With Dynamic Variable
stopwatch = Stopwatch.StartNew();

for (int i = 0; i < ITERATION_COUNT; i++)
{
var var_ngc = new nongeneric_class();
var_ngc.Data = i;
int data = (int)var_ngc.Data;
}

Console.WriteLine("Non-Generic Class With Dynamic Variable: {0}ms", stopwatch.ElapsedMilliseconds);

Console.ReadLine();
}
}


Now the obvious thing that you will notice about this program when it’s run, is that the trend of generic vs non-generic timings are the same (i.e. there is no great difference between using C# ‘var’ keyword or not, even when comparing to boxing and non-boxing types).

The definitive answer to how this works can be found with our friendly tool ildasm.


Even with no understanding of ilasm, you can see with the disassembly of our Main() static function that the local variables types declared for both our ‘var var_ngc’ and ‘nongeneric_class ngc’ variables are exactly the same. The same goes for our ‘var var_gc’ and ‘generic_class gc’ types.

All the C# compiler is actually doing is substituting the ‘var’ keyword for the apropriate variable type… disappointing. Unfortunately there is no magic here 😦

Advertisements