编译时是否对某些反射代码进行了优化?

5

我认为一些使用反射的代码可以在编译时进行优化(我不确定能否称之为优化)。

  • 例如,System.Reflection.MethodInfo.GetCurrentMethod 在同一方法中被调用时总是返回相同的值。

  • 此外,使用表示常量字符串的类名访问类信息没有理由在运行时执行。

我已经进行了测试,结果显示使用反射的代码比没有反射的代码慢了约300倍。

是否有任何编译选项可以实现我想要的效果?


请查看关于反射性能的此文档 - Matthijs
你所询问的内容类似于调用者信息属性(http://msdn.microsoft.com/en-us/library/hh534540(v=vs.110).aspx)。不幸的是,目前没有相当于当前方法信息的属性,因此你最好只需缓存`GetCurrentMethod`返回值。 - Kirill Shlenskiy
我想不出一个关于示例1的具体案例,但对于第二个案例,信息肯定会发生变化(例如,如果您更新了托管类的DLL)。 - Ronan Thibaudau
你完全忽略了这个:https://dev59.com/8G855IYBdhLWcg3w_5im#4045073。内联优化使GetCurrentMethod()返回其他内容。使用字符串的唯一目的是您*不知道*它可能是哪个类。编译器当然也不知道。当然,用反射替换需要纳秒级别的代码,如方法调用,必然会慢得多。 - Hans Passant
3个回答

2

对于 System.Reflection.MethodInfo.GetCurrentMethod 的情况。通常用于获取当前方法调用的名称。

如果这是使用情况。

public void Foo()
{
    var method = System.Reflection.MethodInfo.GetCurrentMethod();
    Log.Log(string.Format("I is inside of {0}", method.Name));
}

那么您应该用以下内容替换它:
public static MemberName([CallerMemberName] memberName = null)
{
    return memberName;
}

public void Foo()
{
    Log.Log(string.Format("I is inside of {0}", MemberName()));
}

0

所有反射操作都可以被缓存并执行一次。我建议这样做是为了保持性能和可扩展性。(例如,在静态构造函数中评估静态字段)

像getcurrent...thing这样的方法是一种懒加载的快捷方式代码。你知道自己在哪里...你可以将你的方法信息保存在静态私有字段中以便使用。


0

.NET 中的反射确实非常缓慢。对此,我们无能为力。

另一方面,您可以使用“fasterflect”http://fasterflect.codeplex.com/,它实现了内置 .net 反射的多个功能,并提高了性能,这可能更适合您。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接