提高反射的调用性能

来源:互联网 发布:c语言求5个数平均值 编辑:程序博客网 时间:2024/06/05 16:33
都说Reflection的性能相当差,但是非用不可的时候也得用,下面是提高反射效率的一个办法。 
要被反射调用的类都实现一个接口,调用的那个类引用这个接口,将反射得来的类都转换为这个接口,然后直接调用,没有必要所有的方法都反射。 
公用的接口
代码: namespace CommonInterface 

    /**//// <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"; 
            } 
        } 
    } 
}
调用者类
代码: 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(); 
        } 
    } 
}
输出结果是:

原创粉丝点击