例如,在Javascript中,强烈建议人们在循环之外放置函数调用以获得更好的性能:
var id = someIdType.ToString();
someList.Where(a => a.id == id) ...
Run Code Online (Sandbox Code Playgroud)
C#怎么样?同样的情况还是编译器/运行时采用内部优化/缓存?
someList.Where(a => a.id == someIdType.ToString()) ...
Run Code Online (Sandbox Code Playgroud)
可能是一个菜鸟问题并且之前一直有人问过,但是找不到参考.
Ale*_*x F 14
C#代码:
List<string> list = new List<string>();
list.Where(a => a == typeof(String).ToString());
Run Code Online (Sandbox Code Playgroud)
MSIL中的Lambda表达式,调试配置:
.method private hidebysig static bool '<Main>b__0'(string a) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 26 (0x1a)
.maxstack 2
.locals init ([0] bool CS$1$0000)
IL_0000: ldarg.0
IL_0001: ldtoken [mscorlib]System.String
IL_0006: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_000b: callvirt instance string [mscorlib]System.Object::ToString()
IL_0010: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_0015: stloc.0
IL_0016: br.s IL_0018
IL_0018: ldloc.0
IL_0019: ret
} // end of method Program::'<Main>b__0'
Run Code Online (Sandbox Code Playgroud)
MSIL中的Lambda表达式,发布配置:
.method private hidebysig static bool '<Main>b__0'(string a) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 22 (0x16)
.maxstack 8
IL_0000: ldarg.0
IL_0001: ldtoken [mscorlib]System.String
IL_0006: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_000b: callvirt instance string [mscorlib]System.Object::ToString()
IL_0010: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_0015: ret
} // end of method Program::'<Main>b__0'
Run Code Online (Sandbox Code Playgroud)
两个版本都调用typeof(String).ToString()),每次迭代都会调用此lambda.在IL级别上没有优化,JIT编译不会在这里添加任何内容.原因是:功能可能有副作用.
lambda将为列表的每个元素执行.因此代码someIdType.ToString()将为每个元素执行.我认为编译器或运行时不会为您缓存它.(AFAIK someIdType将被关闭,但不是.ToString())
编辑: 最初的问题只是关于"是吗?",而不是"为什么?",但仍然有几个评论和其他答案试图回答/演示"为什么?".
对"为什么?"这么感兴趣?我正在编辑我的答案,陈述我的版本"为什么?".也就是说,如果你看一下C#规范,对于任何相关场景,规范都会谈到capturing the variable.. 不是 capturing the expression.这就是编译器行为方式的原因.因为它不在规范中.为什么它不在规范中,是C#设计团队可以回答的问题.如果feature of capturing expressions需要考虑的话,其余的是推测,部分或全部可能有或没有优点.
| 归档时间: |
|
| 查看次数: |
1482 次 |
| 最近记录: |