为何用Delegate.CreateDelegate创建的委托比Lambda及方法委托更快?
反射创建的委托居然比Lambda和声明方法委托更快?
一直以来查反射相关资料时,所有人都在念叨:"反射很慢""反射很慢"。于是我决定亲自测试反射到底有多慢,结果却惊到我了——用反射创建的委托(通过Delegate.CreateDelegate)居然比Lambda创建的委托快约2倍,还比基于已声明方法创建的委托快约4倍!
测试代码
测试用自定义类
这是供委托调用属性获取方法的测试类:
class SomeClass { public SomeClass A { get; set; } // 要获取的属性 public static SomeClass GetA(SomeClass c) { return c.A; } // 声明好的Getter方法 }
三种委托的创建方式
我测试了三种不同方式创建的委托:
PropertyInfo AProp = typeof(SomeClass).GetProperty("A"); // 1 - 反射创建的委托 Func<SomeClass, SomeClass> Getter = (Func<SomeClass, SomeClass>)Delegate.CreateDelegate(typeof(Func<SomeClass, SomeClass>), null, AProp.GetGetMethod()); // 2 - Lambda表达式创建的委托 Func<SomeClass, SomeClass> Getter2 = c => c.A; // 3 - 基于已声明方法创建的委托 Func<SomeClass, SomeClass> Getter3 = SomeClass.GetA;
测试过程
我通过循环调用1000万次来统计每种方式的耗时,测试代码如下:
SomeClass C = new SomeClass(); C.A = new SomeClass(); // 不管A是否赋值,测试结果都不受影响 Stopwatch w; // 测试反射委托 w = Stopwatch.StartNew(); for (int i = 0; i < 10000000; i++) { SomeClass b = Getter(C); } w.Stop(); Console.WriteLine(w.Elapsed); // 测试Lambda委托 w = Stopwatch.StartNew(); for (int i = 0; i < 10000000; i++) { SomeClass b = Getter2(C); } w.Stop(); Console.WriteLine(w.Elapsed); // 测试声明方法委托 w = Stopwatch.StartNew(); for (int i = 0; i < 10000000; i++) { SomeClass b = Getter3(C); } w.Stop(); Console.WriteLine(w.Elapsed); // 直接调用属性(无委托) w = Stopwatch.StartNew(); for (int i = 0; i < 10000000; i++) { SomeClass b = C.A; } w.Stop(); Console.WriteLine(w.Elapsed);
测试结果
首先是Debug模式下的测试结果:
我还特意调换了测试顺序,结果完全一致,说明测试顺序不会影响耗时统计。
Release编译后的补充结果
按照建议改用Release模式编译后,得到的结果如下:
原本我以为Lambda委托的表现会更差,没想到实际结果和我的预想完全不一样。
内容的提问来源于stack exchange,提问作者Daniel Müller
相关产品推荐
相关产品推荐

