C# 静态反射性能

C# 静态反射性能,c#,reflection,C#,Reflection,我在玩Joel Abrahamsson和Daniel Cazzulino的静态反射代码。但我发现它们的表现有点慢,甚至比使用“魔弦”的反射效果还要慢 int迭代次数=1000000; watch.Start(); 对于(int i=0;ic.Name); } 看,停; Console.WriteLine(“[Reflector]:”+watch.elapsedmillesons.ToString()); watch.Reset(); watch.Start(); 对于(int i=0;i

我在玩Joel Abrahamsson和Daniel Cazzulino的静态反射代码。但我发现它们的表现有点慢,甚至比使用“魔弦”的反射效果还要慢

int迭代次数=1000000;
watch.Start();
对于(int i=0;ic.Name);
}
看,停;
Console.WriteLine(“[Reflector]:”+watch.elapsedmillesons.ToString());
watch.Reset();
watch.Start();
对于(int i=0;ic.Name);
}
看,停;
Console.WriteLine(“[StaticReflection]:”+watch.elapsedmillisons.ToString());
结果如下:

  • [反射器]:37823
  • [规则反射]:780
  • [静态反射]:24362
那么为什么我们更喜欢静态反射呢?只是去掉“魔术串”?或者我们应该添加一些缓存来提高静态反射性能?

选择“首选”它的主要原因是编译器进行静态类型检查,以确保不会弄乱它(例如,在混淆时确保它工作)。然而,在我看来,这里的输入错误是一个重要的错误是非常罕见的(这意味着:我不包括您在开发/单元测试期间发现并修复的致命输入错误);因此(因为我是一个性能迷),我通常建议使用最简单的选项(
string
)。这方面的一个特别例子是当人们使用这样的技巧实现
INotifyPropertyChanged
接口时。只需传递一个
字符串
;你看到了吗? 他只使用了代理(而不是表达式树),与正常反射性能相比有了改进

实施的例子

 public static MethodInfo MethodInfo<TRet, A0>(Func<TRet, A0> func0)
{
        return func0.Method;
}
publicstaticmethodinfo方法信息(Func func0)
{
返回func0.Method;
}

谢谢你,马克!有趣的是,几年前Ayende使用.NET2.0做了类似的事情。从他的结论中可以看出,包括通过使用静态反射提高性能。因为他的演示代码不能再下载了。我无法复制它。@Liang he可能是直接检查
字节[]
impl以获得方法句柄-可能明显比表达式快。不幸的是,构建表达式树的速度非常慢,.NET不会自动缓存表达式树。有趣的是,在C#中构建动态表达式(例如使用DynamicObject)的开销比使用表达式的开销要低。@Fule我想这是能够任意参数化它的一个特性。这意味着它们可以缓存一个表达式,该表达式接受一个作为“capture”类的参数。然后,可以对所有呼叫者重复使用。在常规LINQ中,签名是预定义的,因此每次都必须使用捕获实例的.l常量表达式来构建表达式树。@Fule进一步说:是C#编译器,而不是.NET,在这里进行(或不进行)表达式树缓存(但是.NET via dynamic根据解析的类型缓存IL)缓存静态反射的结果。如果您请求Employee.Name,它将在appdomain的生命周期内永远不会更改,因此缓存将是安全的。这不是静态反射
 public static MethodInfo MethodInfo<TRet, A0>(Func<TRet, A0> func0)
{
        return func0.Method;
}