请考虑以下代码:
delegate string StringToString(string s);
MethodInfo trimMethod = typeof(string).GetMethod("Trim", new Type[0]);
var trim = (StringToString)Delegate.CreateDelegate
(typeof(StringToString), trimMethod);
for (int i = 0; i < 1000000; i++)
trim("test");
上面的代码动态调用字符串的Trim
方法一百万次而没有显着的开销。现在,如果我们运行以下代码:
for (int i = 0; i < 1000000; i++)
"test".Trim();
它比第一个更快。第一个必须更快,因为昂贵的动态绑定只发生一次。
我的问题是:为什么第二个比第一个跑得快?
答案 0 :(得分:1)
让我们来看看ILCode
第一个使用委托,显示了许多指令来制作你的修剪,循环在我眼中可怕......
<form name="file_upload" id="file_upload" method="post" action="upload_file.php" target="frame1" enctype="multipart/form-data" >
<input type="file" id="file" name="file[]" multiple onchange="this.form.submit(); display_block();" />
</form>
然后是另一个。
ldtoken [mscorlib]System.String
IL_0025: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_002a: ldstr "Trim"
IL_002f: ldc.i4.0
IL_0030: newarr [mscorlib]System.Type
IL_0035: call instance class [mscorlib]System.Reflection.MethodInfo [mscorlib]System.Type::GetMethod(string,
class [mscorlib]System.Type[])
IL_003a: stloc.1
IL_003b: ldtoken ConsoleApplication1.Program/StringToString
IL_0040: call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
IL_0045: ldloc.1
IL_0046: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::CreateDelegate(class [mscorlib]System.Type,
class [mscorlib]System.Reflection.MethodInfo)
IL_004b: castclass ConsoleApplication1.Program/StringToString
IL_0050: stloc.2
IL_0051: ldc.i4.0
IL_0052: stloc.0
IL_0053: br.s IL_0065
IL_0055: ldloc.2 // start of loop
IL_0056: ldstr "test"
IL_005b: callvirt instance string ConsoleApplication1.Program/StringToString::Invoke(string)
IL_0060: pop
IL_0061: ldloc.0
IL_0062: ldc.i4.1
IL_0063: add
IL_0064: stloc.0
IL_0065: ldloc.0
IL_0066: ldc.i4 0xf4240
IL_006b: clt
IL_006d: stloc.3
IL_006e: ldloc.3
IL_006f: brtrue.s IL_0055 // iterates to next trim here
执行简单任务的大量指令是第一个更慢的原因。例如,对循环中的函数进行四次调用使得它比只有一次调用的第二次调用慢。不同基准测试的原因很可能是您的测试环境,其他进程同时进行。