提高反射的调用性能
都说Reflection的性能相当差,但是非用不可的时候也得用,下面是提高反射效率的一个办法。
要被反射调用的类都实现一个接口,调用的那个类引用这个接口,将反射得来的类都转换为这个接口,然后直接调用,没有必要所有的方法都反射。
公用的接口
被反射调用的类
调用者类
要被反射调用的类都实现一个接口,调用的那个类引用这个接口,将反射得来的类都转换为这个接口,然后直接调用,没有必要所有的方法都反射。
公用的接口
namespace CommonInterface
{
/// <summary>
/// 公用的接口
/// </summary>
public interface IFoo
{
string getName();
string Name{get;}
}
}
{
/// <summary>
/// 公用的接口
/// </summary>
public interface IFoo
{
string getName();
string Name{get;}
}
}
被反射调用的类
using CommonInterface;
namespace ClassLibOne
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
public class FooOne:IFoo
{
public FooOne()
{
}
public string getName()
{
return "FooOne";
}
public string Name
{
get
{
return "FooOne";
}
}
}
}
namespace ClassLibOne
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
public class FooOne:IFoo
{
public FooOne()
{
}
public string getName()
{
return "FooOne";
}
public string Name
{
get
{
return "FooOne";
}
}
}
}
调用者类
using System;
using System.Reflection;
using CommonInterface;
namespace ReflectionMain
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
public class ReflectionMain
{
delegate string DgetName();
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//加载
Assembly assembly = Assembly.LoadFile("D:\\Project2003\\BankTest\\Reflection\\ReflectionTest\\ReflectionMain\\bin\\Debug\\ClassLibOne.dll");
Type type = assembly.GetType("ClassLibOne.FooOne");
ConstructorInfo conInfo = type.GetConstructor(new Type[]{});
object fooOne = conInfo.Invoke(new object[]{});
//反射调用
DateTime startR = DateTime.Now;
for(int i=0;i<100000;i++)
{
object rtn;
rtn = type.GetMethod("getName").Invoke(fooOne,new object[]{});
}
TimeSpan spanR = DateTime.Now - startR;
Console.WriteLine("反射调用100,000次:"+spanR.ToString());
//转换成接口后调用
DateTime startI = DateTime.Now;
for(int i=0;i<1000000;i++)
{
IFoo foo = (IFoo)fooOne;
foo.getName();
}
TimeSpan spanI = DateTime.Now - startI;
Console.WriteLine("转换成接口后调用1,000,000次:"+spanI.ToString());
//用委托调用
DateTime startDA = DateTime.Now;
IFoo fooo = (IFoo)fooOne;
DgetName dgn = new DgetName(fooo.getName);
for(int i=0;i<10000;i++)
{
IFoo foo = (IFoo)fooOne;
dgn += new DgetName(foo.getName);
}
TimeSpan spanDA = DateTime.Now - startDA;
Console.WriteLine("用委托调用__添加到委托10,000:"+spanDA.ToString());
DateTime startD = DateTime.Now;
dgn();
TimeSpan spanD = DateTime.Now - startD;
Console.WriteLine("用委托调用10,000:"+spanD.ToString());
Console.ReadLine();
}
}
}
using System.Reflection;
using CommonInterface;
namespace ReflectionMain
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
public class ReflectionMain
{
delegate string DgetName();
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
//加载
Assembly assembly = Assembly.LoadFile("D:\\Project2003\\BankTest\\Reflection\\ReflectionTest\\ReflectionMain\\bin\\Debug\\ClassLibOne.dll");
Type type = assembly.GetType("ClassLibOne.FooOne");
ConstructorInfo conInfo = type.GetConstructor(new Type[]{});
object fooOne = conInfo.Invoke(new object[]{});
//反射调用
DateTime startR = DateTime.Now;
for(int i=0;i<100000;i++)
{
object rtn;
rtn = type.GetMethod("getName").Invoke(fooOne,new object[]{});
}
TimeSpan spanR = DateTime.Now - startR;
Console.WriteLine("反射调用100,000次:"+spanR.ToString());
//转换成接口后调用
DateTime startI = DateTime.Now;
for(int i=0;i<1000000;i++)
{
IFoo foo = (IFoo)fooOne;
foo.getName();
}
TimeSpan spanI = DateTime.Now - startI;
Console.WriteLine("转换成接口后调用1,000,000次:"+spanI.ToString());
//用委托调用
DateTime startDA = DateTime.Now;
IFoo fooo = (IFoo)fooOne;
DgetName dgn = new DgetName(fooo.getName);
for(int i=0;i<10000;i++)
{
IFoo foo = (IFoo)fooOne;
dgn += new DgetName(foo.getName);
}
TimeSpan spanDA = DateTime.Now - startDA;
Console.WriteLine("用委托调用__添加到委托10,000:"+spanDA.ToString());
DateTime startD = DateTime.Now;
dgn();
TimeSpan spanD = DateTime.Now - startD;
Console.WriteLine("用委托调用10,000:"+spanD.ToString());
Console.ReadLine();
}
}
}
输出结果是: