dynamic類型的效率
效率問題應該是大家很關心的, 我的感覺:不要對動態語言有很高的效率抱有太大的希望,但另一方面,算法的 設計對效率的影響非常大,功能與性能經常存在一個平衡點。
要分析其 效率,就要看看編譯後內部都干了些啥,方法是寫些簡單的代碼,查看IL。
代碼:
using System;
namespace Xianfen.Net.TestDynamic
{
class Program
{
static void Main()
{
dynamic d = "str";
d.ToString();
}
}
}
對應的IL代碼:
.class private auto ansi beforefIEldinit Program
extends [mscorlib]System.Object
{
.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: call instance void [mscorlib] System.Object::.ctor()
L_0006: ret
}
.method private hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 9
.locals init (
[0] object d,
[1] class [Microsoft.CSharp] Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[] CS$0$0000)
L_0000: ldstr "str"
L_0005: stloc.0
L_0006: ldsfld class [System.Core] System.Runtime.CompilerServices.CallSite`1<class [mscorlib] System.Action`2<class [System.Core] System.Runtime.CompilerServices.CallSite, object>> Xianfen.Net.TestDynamic.Program/<Main>o__SiteContainer0::<> ;p__Site1
L_000b: brtrue.s L_003f
L_000d: ldc.i4.0
L_000e: ldstr "ToString"
L_0013: ldtoken Xianfen.Net.TestDynamic.Program
L_0018: call class [mscorlib]System.Type [mscorlib] System.Type::GetTypeFromHandle(valuetype [mscorlib] System.RuntimeTypeHandle)
L_001d: ldnull
L_001e: ldc.i4.1
L_001f: newarr [Microsoft.CSharp] Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo
L_0024: stloc.1
L_0025: ldloc.1
L_0026: ldc.i4.0
L_0027: ldc.i4.0
L_0028: ldnull
L_0029: newobj instance void [Microsoft.CSharp] Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::.ctor(valuetype [Microsoft.CSharp] Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)
L_002e: stelem.ref
L_002f: ldloc.1
L_0030: newobj instance void [Microsoft.CSharp] Microsoft.CSharp.RuntimeBinder.CSharpInvokeMemberBinder::.ctor (valuetype [Microsoft.CSharp] Microsoft.CSharp.RuntimeBinder.CSharpCallFlags, string, class [mscorlib]System.Type, class [mscorlib] System.Collections.Generic.IEnumerable`1<class [mscorlib] System.Type>, class [mscorlib] System.Collections.Generic.IEnumerable`1<class [Microsoft.CSharp] Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)
L_0035: call class [System.Core] System.Runtime.CompilerServices.CallSite`1<!0> [System.Core] System.Runtime.CompilerServices.CallSite`1<class [mscorlib] System.Action`2<class [System.Core] System.Runtime.CompilerServices.CallSite, object>>::Create(class [System.Core]System.Runtime.CompilerServices.CallSiteBinder)
L_003a: stsfld class [System.Core] System.Runtime.CompilerServices.CallSite`1<class [mscorlib] System.Action`2<class [System.Core] System.Runtime.CompilerServices.CallSite, object>> Xianfen.Net.TestDynamic.Program/<Main>o__SiteContainer0::<> ;p__Site1
L_003f: ldsfld class [System.Core] System.Runtime.CompilerServices.CallSite`1<class [mscorlib] System.Action`2<class [System.Core] System.Runtime.CompilerServices.CallSite, object>> Xianfen.Net.TestDynamic.Program/<Main>o__SiteContainer0::<> ;p__Site1
L_0044: ldfld !0 [System.Core] System.Runtime.CompilerServices.CallSite`1<class [mscorlib] System.Action`2<class [System.Core] System.Runtime.CompilerServices.CallSite, object>>::Target
L_0049: ldsfld class [System.Core] System.Runtime.CompilerServices.CallSite`1<class [mscorlib] System.Action`2<class [System.Core] System.Runtime.CompilerServices.CallSite, object>> Xianfen.Net.TestDynamic.Program/<Main>o__SiteContainer0::<> ;p__Site1
L_004e: ldloc.0
L_004f: callvirt instance void [mscorlib] System.Action`2<class [System.Core] System.Runtime.CompilerServices.CallSite, object>::Invoke(!0, !1)
L_0054: ret
}
.class abstract auto ansi sealed nested private beforefIEldinit <Main>o__SiteContainer0
extends [mscorlib]System.Object
{
.custom instance void [mscorlib] System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
.fIEld public static class [System.Core] System.Runtime.CompilerServices.CallSite`1<class [mscorlib] System.Action`2<class [System.Core] System.Runtime.CompilerServices.CallSite, object>> <>p__Site1
}
}