为什么通过接口反射调用方法要快得多
为什么通过反射调用方法比创建接口然后通过反射调用要慢得多。第一个版本显示了乏味的方式,另一个版本显示了增强的方式?
// first version
class A
{
public void fn()
{
}
}
void Main(String[]x)
{
Type type = typeof(A);
object obj = Activator.CreateInstance(type);
type.InvokeMember("fn", BindingFlags.Public, null, obj, null);
}
//second verison
interface IA
{
void fn();
}
class A :IA
{
public void fn()
{
}
}
void Main(String []x)
{
Type type = typeof(A);
IA obj =(IA) Activator.CreateInstance(type);
obj.fn();
}
why invoking a method by reflection is much slower than making a interface then recall it by reflection. the first version shows the tedious way the other version shows the enhanced way??
// first version
class A
{
public void fn()
{
}
}
void Main(String[]x)
{
Type type = typeof(A);
object obj = Activator.CreateInstance(type);
type.InvokeMember("fn", BindingFlags.Public, null, obj, null);
}
//second verison
interface IA
{
void fn();
}
class A :IA
{
public void fn()
{
}
}
void Main(String []x)
{
Type type = typeof(A);
IA obj =(IA) Activator.CreateInstance(type);
obj.fn();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
基于反射的方法调用非常慢,因为您需要在运行时执行成员查找和参数绑定等操作。
相比之下,接口方法是通过使用 vtable 的常规
callvirt
指令来调用的。Reflection-based method calls are extremely slow, since you need to do member lookup and parameter binding and other things at runtime.
Interface methods, by contrast, are called with a regular
callvirt
instruction using the vtable.为了进行同类比较,请调用 Type.GetConstructor 来获取 ConstructorInfo 对象并调用它来创建对象。然后,您可以保留 ConstructorInfo 并重复使用。相比之下,Activator 的速度非常慢。
回答有关反射方式如何工作的问题:
Activator 在加载的程序集的元数据中搜索与您指定的类型名称相匹配的类型名称。然后,它搜索类似于 Type.GetConstructor 的构造函数,该构造函数返回 ConstructorInfo。它调用该构造函数并返回该对象。
然后,当您调用 Type.InvokeMember 时,您将再次使用反射,查询类的元数据以查找匹配的方法签名。它作为 MethodInfo 返回,然后被调用。
反射中的困难工作不是调用本身,而是对类型、构造函数和方法的元数据搜索。这就是为什么我说您可以通过重用 ConstructorInfo 和 MethodInfo 对象来对反射对象进行相对高性能的方法调用。您会发现重复调用 MethodInfo.Invoke 比 Type.InvokeMember 快得多
For an apples to apples comparison, call Type.GetConstructor to get a ConstructorInfo object and invoke that to create your object. You can then keep the ConstructorInfo around and reuse. Activator is very slow in comparison.
Answering your question about how the reflection way works:
Activator searches the Metadata of the loaded assemblies for a type name that matches what you've specified. It then searches for a constructor similar to Type.GetConstructor, which returns a ConstructorInfo. It calls that constructor and returns the object.
Then when you call Type.InvokeMember, you're using reflection again, querying the metadata of the class to find the matching method signature. This is returned as a MethodInfo which is then invoked.
The hard work in reflection isn't the call itself, it's the metadata searches for the type, constructor, and method. That's why I was saying you can make relatively high performance method calls on reflected objects by reusing the ConstructorInfo and MethodInfo objects. You'll find repeatedly calling MethodInfo.Invoke is much faster than Type.InvokeMember