我在玩Joel Abrahamsson的博客和Daniel Cazzulino的博客中的静态反射代码。但我发现他们的表现有点慢,甚至与使用"魔术串"的反射相比也是如此。
int iterations = 1000000;
watch.Start();
for (int i = 0; i < iterations; i++)
{
var propertyOfName = Reflect<Employee>.GetProperty(c => c.Name);
}
watch.Stop();
Console.WriteLine("[Reflector]: " + watch.ElapsedMilliseconds.ToString());
watch.Reset();
watch.Start();
for (int i = 0; i < iterations; i++)
{
var propertyName = typeof (Employee).GetProperty("Name");
}
watch.Stop();
Console.WriteLine("[Regular Reflection]: " + watch.ElapsedMilliseconds.ToString());
watch.Reset();
watch.Start();
for (int i = 0; i < iterations; i++)
{
var propertyName = StaticReflection.GetMemberName<Employee>(c => c.Name);
}
watch.Stop();
Console.WriteLine("[StaticReflection]: " + watch.ElapsedMilliseconds.ToString());
结果如下:
- 【反射器】:37823
- 【规则反射】:780
- 【静态反射】:24362
那么,为什么我们更喜欢静态反射呢?只是去掉"魔术串"?或者我们应该添加一些缓存来提高静态反射性能?
"喜欢"它的主要原因是编译器的静态类型检查,以确保你不会把它弄得一团糟(例如,如果你混淆了它,也确保它能工作(。然而,IMO,这里的拼写错误是一个显著的错误,这是非常罕见的(意思是:我不包括你在开发/单元测试期间发现并修复的脑死亡拼写错误(;所以(因为我是一个性能专家(我通常建议使用最简单的选项(string
(。一个特别的例子是当人们使用这样的技巧来实现INotifyPropertyChanged
接口时。只需通过一个string
;p
你看到了吗http://ayende.com/blog/779/static-reflection?他只使用了代理(而不是表达式树(,并且与正常的反射性能相比有所改进。
实施示例
public static MethodInfo MethodInfo<TRet, A0>(Func<TRet, A0> func0)
{
return func0.Method;
}