By Jeff Keslinke


2008-12-10 17:19:45 8 Comments

Earlier I asked a question about why I see so many examples use the varkeyword and got the answer that while it is only necessary for anonymous types, that it is used nonetheless to make writing code 'quicker'/easier and 'just because'.

Following this link ("C# 3.0 - Var Isn't Objec") I saw that var gets compiled down to the correct type in the IL (you will see it about midway down article).

My question is how much more, if any, IL code does using the var keyword take, and would it be even close to having a measurable level on the performance of the code if it was used everywhere?

12 comments

@Silvio Garcez 2019-05-24 00:25:06

It's depends of situation, if you try use, this code bellow.

The expression is converted to "OBJECT" and decrease so much the performance, but it's a isolated problem.

CODE:

public class Fruta
{
    dynamic _instance;

    public Fruta(dynamic obj)
    {
        _instance = obj;
    }

    public dynamic GetInstance()
    {
        return _instance;
    }
}

public class Manga
{
    public int MyProperty { get; set; }
    public int MyProperty1 { get; set; }
    public int MyProperty2 { get; set; }
    public int MyProperty3 { get; set; }
}

public class Pera
{
    public int MyProperty { get; set; }
    public int MyProperty1 { get; set; }
    public int MyProperty2 { get; set; }
}

public class Executa
{
    public string Exec(int count, int value)
    {
        int x = 0;
        Random random = new Random();
        Stopwatch time = new Stopwatch();
        time.Start();

        while (x < count)
        {
            if (value == 0)
            {
                var obj = new Pera();
            }
            else if (value == 1)
            {
                Pera obj = new Pera();
            }
            else if (value == 2)
            {
                var obj = new Banana();
            }
            else if (value == 3)
            {
                var obj = (0 == random.Next(0, 1) ? new Fruta(new Manga()).GetInstance() : new Fruta(new Pera()).GetInstance());
            }
            else
            {
                Banana obj = new Banana();
            }

            x++;
        }

        time.Stop();
        return time.Elapsed.ToString();
    }

    public void ExecManga()
    {
        var obj = new Fruta(new Manga()).GetInstance();
        Manga obj2 = obj;
    }

    public void ExecPera()
    {
        var obj = new Fruta(new Pera()).GetInstance();
        Pera obj2 = obj;
    }
}

Above results with ILSPY.

public string Exec(int count, int value)
{
    int x = 0;
    Random random = new Random();
    Stopwatch time = new Stopwatch();
    time.Start();

    for (; x < count; x++)
    {
        switch (value)
        {
            case 0:
                {
                    Pera obj5 = new Pera();
                    break;
                }
            case 1:
                {
                    Pera obj4 = new Pera();
                    break;
                }
            case 2:
                {
                    Banana obj3 = default(Banana);
                    break;
                }
            case 3:
                {
                    object obj2 = (random.Next(0, 1) == 0) ? new Fruta(new Manga()).GetInstance() : new Fruta(new Pera()).GetInstance();
                    break;
                }
            default:
                {
                    Banana obj = default(Banana);
                    break;
                }
        }
    }
time.Stop();
return time.Elapsed.ToString();
}

If you wish execute this code use the code bellow, and get the difference of times.

        static void Main(string[] args)
    {
        Executa exec = new Executa();            
        int x = 0;
        int times = 4;
        int count = 100000000;
        int[] intanceType = new int[4] { 0, 1, 2, 3 };

        while(x < times)
        {                
            Parallel.For(0, intanceType.Length, (i) => {
                Console.WriteLine($"Tentativa:{x} Tipo de Instancia: {intanceType[i]} Tempo Execução: {exec.Exec(count, intanceType[i])}");
            });
            x++;
        }

        Console.ReadLine();
    }

Regards

@RichardOD 2009-11-18 14:42:02

As nobody has mentioned reflector yet...

If you compile the following C# code:

static void Main(string[] args)
{
    var x = "hello";
    string y = "hello again!";
    Console.WriteLine(x);
    Console.WriteLine(y);
}

Then use reflector on it, you get:

// Methods
private static void Main(string[] args)
{
    string x = "hello";
    string y = "hello again!";
    Console.WriteLine(x);
    Console.WriteLine(y);
}

So the answer is clearly no runtime performance hit!

@Joel Coehoorn 2008-12-10 17:21:40

There's no extra IL code for the var keyword: the resulting IL should be identical for non-anonymous types. If the compiler can't create that IL because it can't figure out what type you intended to use, you'll get a compiler error.

The only trick is that var will infer an exact type where you may have chosen an Interface or parent type if you were to set the type manually.


Update 8 Years Later

I need to update this as my understanding has changed. I now believe it may be possible for var to affect performance in the situation where a method returns an interface, but you would have used an exact type. For example, if you have this method:

IList<int> Foo()
{
    return Enumerable.Range(0,10).ToList();
}

Consider these three lines of code to call the method:

List<int> bar1 = Foo();
IList<int> bar = Foo();
var bar3 = Foo();

All three compile and execute as expected. However, the first two lines are not exactly the same, and the third line will match the second, rather than the first. Because the signature of Foo() is to return an IList<int>, that is how the compiler will build the bar3 variable.

From a performance standpoint, mostly you won't notice. However, there are situations where the performance of the third line may not be quite as fast as the performance of the first. As you continue to use the bar3 variable, the compiler may not be able to dispatch method calls the same way.

Note that it's possible (likely even) the jitter will be able to erase this difference, but it's not guaranteed. Generally, you should still consider var to be a non-factor in terms of performance. It's certainly not at all like using a dynamic variable. But to say it never makes a difference at all may be overstating it.

@Brian Rasmussen 2008-12-10 18:58:15

Not only should the IL be identical - it is identical. var i = 42; compiles to exactly the same code as int i = 42;

@Athiwat Chunlakhan 2009-08-19 17:10:59

Note that I used var in the IDE after compile and use reflector to extract the code. We get this. string fileName = Console.ReadLine(); string input = Console.ReadLine();

@Nelson Rothermel 2012-05-09 17:26:31

@BrianRasmussen: I know your post is old is old, but I assume var i = 42; (infers type is int) is NOT identical to long i = 42;. So in some cases you may be making incorrect assumptions about the type inference. This could cause elusive/edge case runtime errors if the value doesn't fit. For that reason, it may still be a good idea to be explicit when the value doesn't have an explicit type. So for example, var x = new List<List<Dictionary<int, string>()>()>() would be acceptable, but var x = 42 is somewhat ambiguous and should be written as int x = 42. But to each their own...

@Brian Rasmussen 2012-05-09 18:47:56

@NelsonRothermel: var x = 42; isn't ambiguous. Integer literals are of the type int. If you want a literal long you write var x = 42L;.

@puretppc 2014-01-19 20:08:27

Uhm what does IL stand for in C#? I never really heard of it.

@Joel Coehoorn 2014-01-20 22:24:12

Intermediate language. It's similar to Java's bytecode and reads a bit like assembler.

@Servy 2016-11-17 21:48:46

In your example of the 3 lines of code that behave differently the first line doesn't compile. The second and third lines, which both do compile, do exactly the same thing. If Foo returned a List, rather than an IList, then all three lines would compile but the third line would behave like the first line, not the second.

@Lucas Trzesniewski 2016-11-24 09:21:51

Could you please fix your answer, as the "update" part is plain wrong. See Servy's comment above.

@TurdPile 2016-12-19 17:33:04

If you reversed the IList and List in the example, it'd be correct. List implements IList, not the otherway around.

@Mike Manard 2017-04-03 19:58:53

I'm a bit late to the party, but the line "List<int> bar1 = Foo();" would throw a compile-time error. You can’t assume an abstraction (e.g. IList<int>) is a particular concretion (e.g. List<int>). That won't compile at all, unless I'm missing something here.

@GettnDer 2017-04-05 14:54:05

^ What Mike said, this should not compile, you need an explicit cast, List is not the only implementation of IList, so yea, duh

@Groo 2017-06-08 08:57:31

List<int> y = (IList<int>)x; won't compile, you should fix this.

@Georg 2019-08-06 06:12:12

I just stumbled over this post and was suprised that it misses a very important point even though so many people looked over it: You can in fact also use var in a foreach loop like foreach (var item in collection). This is an entirely different story than foreach (string item in collection). For the latter, sometimes an additional call to Cast<T> is generated, which is not the case for var.

@Herohtar 2019-11-30 06:35:54

Pointed out multiple times over the years and still not fixed, but the example is wrong. The function needs to return List. Performance would still be potentially affected, but in a "good" way.

@Daniel Lorenz 2016-04-01 20:17:50

"var" is one of those things that people either love or hate (like regions). Though, unlike regions, var is absolutely necessary when creating anonymous classes.

To me, var makes sense when you are newing up an object directly like:

var dict = new Dictionary<string, string>();

That being said, you can easily just do:

Dictionary<string, string> dict = new and intellisense will fill in the rest for you here.

If you only want to work with a specific interface, then you can't use var unless the method you are calling returns the interface directly.

Resharper seems to be on the side of using "var" all over, which may push more people to do it that way. But I kind of agree that it is harder to read if you are calling a method and it isn't obvious what is being returned by the name.

var itself doesn't slow things down any, but there is one caveat to this that not to many people think about. If you do var result = SomeMethod(); then the code after that is expecting some sort of result back where you'd call various methods or properties or whatever. If SomeMethod() changed its definition to some other type but it still met the contract the other code was expecting, you just created a really nasty bug (if no unit/integration tests, of course).

@mjb 2014-07-21 01:55:18

I always use the word var in web articles or guides writings.

The width of the text editor of online article is small.

If I write this:

SomeCoolNameSpace.SomeCoolClassName.SomeCoolSubClassName coolClass = new SomeCoolNameSpace.SomeCoolClassName.SomeCoolSubClassName();

You will see that above rendered pre code text is too long and flows out of the box, it gets hidden. The reader needs to scroll to the right to see the complete syntax.

That's why I always use the keyword var in web article writings.

var coolClass = new SomeCoolNameSpace.SomeCoolClassName.SomeCoolSubClassName();

The whole rendered pre code just fit within the screen.

In practice, for declaring object, I seldom use var, I rely on intellisense to declare object faster.

Example:

SomeCoolNamespace.SomeCoolObject coolObject = new SomeCoolNamespace.SomeCoolObject();

But, for returning object from a method, I use var to write code faster.

Example:

var coolObject = GetCoolObject(param1, param2);

@ChrisH 2017-11-20 23:05:01

If you're writing for students, then eat your own dog food and always write it the same "correct" way, consistently. Students often take things 100% verbatim and to heart, and will begin using any sloppy habits they pick up along the way. $.02

@ChrisH 2015-08-20 15:29:44

So, to be clear, it's a lazy coding style. I prefer native types, given the choice; I'll take that extra bit of "noise" to ensure I'm writing and reading exactly what I think I am at code/debug time. * shrug *

@Anders 2019-03-31 09:57:27

Thats just your subjective view and not an answer to the question about performance. The right answer is that it has no impact on performance. I voted for close

@Herohtar 2019-11-30 08:59:55

This doesn't answer the question of whether var affects performance at all; you're just stating your opinion on whether people should use it.

@ChrisH 2019-12-01 14:52:47

Inferring type from value later, for instance, switching from int 5 to float 5.25, can absolutely cause performance issues. * shrug *

@Herohtar 2019-12-05 22:56:13

No, that will not cause any performance issues; you'll get build errors in any places that were expecting a variable of type int because it can't automatically convert the float, but that's exactly the same thing that would happen if you explicitly used int and then changed to float. In any case, your answer still does not answer the question of "does using var affect performance?" (particularly in terms of generated IL)

@alex 2008-12-10 17:28:33

If the compiler can do automatic type inferencing, then there wont be any issue with performance. Both of these will generate same code

var    x = new ClassA();
ClassA x = new ClassA();

however, if you are constructing the type dynamically (LINQ ...) then var is your only question and there is other mechanism to compare to in order to say what is the penalty.

@ljs 2008-12-10 17:24:20

As Joel says, the compiler works out at compile-time what type var should be, effectively it's just a trick the compiler performs to save keystrokes, so for example

var s = "hi";

gets replaced by

string s = "hi";

by the compiler before any IL is generated. The Generated IL will be exactly the same as if you'd typed string.

@Rob 2011-02-22 20:15:20

For the following method:

   private static void StringVsVarILOutput()
    {
        var string1 = new String(new char[9]);

        string string2 = new String(new char[9]);
    }

The IL Output is this:

        {
          .method private hidebysig static void  StringVsVarILOutput() cil managed
          // Code size       28 (0x1c)
          .maxstack  2
          .locals init ([0] string string1,
                   [1] string string2)
          IL_0000:  nop
          IL_0001:  ldc.i4.s   9
          IL_0003:  newarr     [mscorlib]System.Char
          IL_0008:  newobj     instance void [mscorlib]System.String::.ctor(char[])
          IL_000d:  stloc.0
          IL_000e:  ldc.i4.s   9
          IL_0010:  newarr     [mscorlib]System.Char
          IL_0015:  newobj     instance void [mscorlib]System.String::.ctor(char[])
          IL_001a:  stloc.1
          IL_001b:  ret
        } // end of method Program::StringVsVarILOutput

@Brian Rudolph 2008-12-10 17:41:10

There is no runtime performance cost to using var. Though, I would suspect there to be a compiling performance cost as the compiler needs to infer the type, though this will most likely be negligable.

@Jimmy 2008-12-10 17:47:20

the RHS has to have its type calculated anyways -- the compiler would catch mismatched types and throw an error, so not really a cost there, I think.

@jalf 2008-12-10 17:30:41

I don't think you properly understood what you read. If it gets compiled to the correct type, then there is no difference. When I do this:

var i = 42;

The compiler knows it's an int, and generate code as if I had written

int i = 42;

As the post you linked to says, it gets compiled to the same type. It's not a runtime check or anything else requiring extra code. The compiler just figures out what the type must be, and uses that.

@ChrisH 2019-03-31 19:07:20

Right, but what if later you i = i - someVar and someVar = 3.3. i is an Int, now. It's better to be explicit not only to give the compiler a head start on finding flaws, but also to minimize runtime errors or process-slowing type conversions. * shrug * It also makes the code better for self-describing. I've been doing this a long, long time. I'll take "noisy" code with explicit types every time, given the choice.

@Michael Burr 2008-12-10 17:23:28

The C# compiler infers the true type of the var variable at compile time. There's no difference in the generated IL.

Related Questions

Sponsored Content

34 Answered Questions

[SOLVED] What's the difference between using "let" and "var"?

5 Answered Questions

10 Answered Questions

[SOLVED] Improve INSERT-per-second performance of SQLite?

15 Answered Questions

[SOLVED] Efficiency of Java "Double Brace Initialization"?

9 Answered Questions

[SOLVED] Swift Beta performance: sorting arrays

14 Answered Questions

[SOLVED] What's the difference between dynamic (C# 4) and var?

  • 2009-06-07 09:45:10
  • Ivan Prodanov
  • 81857 View
  • 193 Score
  • 14 Answer
  • Tags:   c# dynamic

86 Answered Questions

[SOLVED] Use of var keyword in C#

Sponsored Content