Earlier I asked a question about why I see so many examples use the var
keyword 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?
This question is related to
c#
performance
variables
var
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.
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.
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.
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 *
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
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.
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.
The C# compiler infers the true type of the var
variable at compile time. There's no difference in the generated IL.
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.
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
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);
The C# compiler infers the true type of the var
variable at compile time. There's no difference in the generated IL.
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.
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);
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.
The C# compiler infers the true type of the var
variable at compile time. There's no difference in the generated IL.
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.
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 *
The C# compiler infers the true type of the var
variable at compile time. There's no difference in the generated IL.
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!
"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).
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!
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
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.
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.
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.
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
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.
"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).
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.
Source: Stackoverflow.com