静态反射性能

Lia*_* Wu 9 c# reflection

我正在播放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());
Run Code Online (Sandbox Code Playgroud)

结果如下:

  • [Reflector]:37823
  • [定期反思]:780
  • [静态反思]:24362

那么为什么我们更喜欢静态反射呢?只需删除"魔法字符串"?或者我们应该添加一些缓存来提高静态反射性能?

Mar*_*ell 4

“更喜欢”它的主要原因是编译器进行静态类型检查,以确保您不会弄乱它(例如,如果您进行混淆,则确保它可以工作)。然而,在我看来,这里的拼写错误是一个重大错误的情况非常罕见(意思是:我不包括您在开发/单元测试期间发现并修复的脑死亡拼写错误);所以(因为我是一个性能狂)我通常建议使用最简单的选项(string)。一个具体的例子是人们INotifyPropertyChanged使用这样的技巧来实现界面。只需传递一个string;p

  • @Fule我想这是一个能够任意参数化它的功能。这意味着它们可以缓存采用“捕获”类参数的表达式。然后,所有调用者都可以重复使用该信息。在常规 LINQ 中,签名是预先定义的,因此每次都必须使用捕获实例的 .la ConstantExpression 构建表达式树。 (2认同)