例如,在 Javascript 中,强烈建议将函数调用放在循环之外以获得更好的性能:
var id = someIdType.ToString();
someList.Where(a => a.id == id) ...
C# 怎么样?相同情况还是编译器/运行时使用内部优化/缓存?
someList.Where(a => a.id == someIdType.ToString()) ...
可能是菜鸟问题,之前有人问过,但找不到引用。
最佳答案
C#代码:
List<string> list = new List<string>();
list.Where(a => a == typeof(String).ToString());
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'
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'
两个版本都调用 typeof(String).ToString())
,此 lambda 会在每次迭代时调用。没有对 IL 级别的优化,JIT 编译不会在此处添加任何内容。原因是:函数可能有副作用。
关于c# - C# 是否在循环/lambda 语句中自动优化代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26773611/