Jef*_*nke 223 c# variables performance var
之前我问了一个问题,为什么我看到这么多的例子都使用了这个var关键字并得到了答案,虽然它只是匿名类型所必需的,但它仍然被用来使编写代码"更快"/更容易和"只是因为".
在这个链接("C#3.0 - Var不是Objec")之后,我看到它var被编译成IL中的正确类型(你会在中间的文章中看到它).
我的问题是IL代码使用var关键字take 会有多少(如果有的话),如果在任何地方使用它,它是否会接近于对代码性能有可衡量的水平?
Joe*_*orn 305
var关键字没有额外的IL代码:对于非匿名类型,生成的IL应该是相同的.如果编译器无法创建该IL,因为它无法确定您打算使用的类型,则会出现编译器错误.
唯一的技巧是,var如果要手动设置类型,将推断出您可能选择了接口或父类型的确切类型.
我的理解已经改变,我需要更新它.我现在相信,var在方法返回接口的情况下,可能会影响性能,但您会使用精确类型.例如,如果您有此方法:
IList<int> Foo()
{
return Enumerable.Range(0,10).ToList();
}
Run Code Online (Sandbox Code Playgroud)
考虑这三行代码来调用该方法:
List<int> bar1 = Foo();
IList<int> bar = Foo();
var bar3 = Foo();
Run Code Online (Sandbox Code Playgroud)
所有三个按预期编译和执行.但是,前两行不完全相同,第三行与第二行匹配,而不是第一行.因为签名Foo()是返回一个IList<int>,这就是编译器将如何构建bar3变量.
从表现的角度来看,大多数情况下你都不会注意到.但是,有些情况下第三行的性能可能不如第一行的性能快.当您继续使用该bar3变量时,编译器可能无法以相同的方式调度方法调用.
请注意,可能(甚至可能)抖动可以消除这种差异,但不能保证.通常,您仍然应该考虑var在性能方面不是一个因素.它当然不像使用dynamic变量.但要说它根本没有任何区别可能会夸大它.
ljs*_*ljs 71
正如Joel所说,编译器在编译时计算 var应该是什么类型,实际上它只是编译器为保存击键而执行的一个技巧,例如
var s = "hi";
Run Code Online (Sandbox Code Playgroud)
被替换为
string s = "hi";
Run Code Online (Sandbox Code Playgroud)
在生成任何IL之前由编译器生成.生成的IL 与您键入的字符串完全相同.
Ric*_*dOD 25
至今没有人提到反射器......
如果编译以下C#代码:
static void Main(string[] args)
{
var x = "hello";
string y = "hello again!";
Console.WriteLine(x);
Console.WriteLine(y);
}
Run Code Online (Sandbox Code Playgroud)
然后在上面使用反射器,你得到:
// Methods
private static void Main(string[] args)
{
string x = "hello";
string y = "hello again!";
Console.WriteLine(x);
Console.WriteLine(y);
}
Run Code Online (Sandbox Code Playgroud)
所以答案很明显没有运行时性能!
Rob*_*Rob 17
对于以下方法:
private static void StringVsVarILOutput()
{
var string1 = new String(new char[9]);
string string2 = new String(new char[9]);
}
Run Code Online (Sandbox Code Playgroud)
IL输出是这样的:
{
.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
Run Code Online (Sandbox Code Playgroud)
Chr*_*isH 14
所以,要清楚,这是一种懒惰的编码风格.考虑到选择,我更喜欢原生类型; 我将采取额外的"噪音",以确保我正在编写和阅读我认为我在代码/调试时的确切内容.*耸肩*
我认为你没有正确理解你所读到的内容.如果它被编译为正确的类型,那么是没有什么区别.当我这样做:
var i = 42;
Run Code Online (Sandbox Code Playgroud)
编译器知道它是一个int,并生成代码,就像我写的一样
int i = 42;
Run Code Online (Sandbox Code Playgroud)
正如您链接的帖子所说,它被编译为相同的类型.它不是运行时检查或其他需要额外代码的东西.编译器只是弄清楚类型必须是什么,并使用它.
使用var没有运行时性能成本.虽然,我怀疑编译器需要推断出类型的编译性能成本,尽管这很可能是可以忽略不计的.
| 归档时间: |
|
| 查看次数: |
97026 次 |
| 最近记录: |