打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
反射VS委托,到底谁更快?

反射VS委托,到底谁更快?

       有时候我们需要动态调用一个方法,到底用什么方法呢?很多人想到了反射,有的人也想到了委托。大家都知道反射很慢,因为反射的类型不安全和以寻找字符串的方式来匹配相对应的成员,所以也有的人用委托,那到底谁更快呢?来看一个demo:

   

 1  public interface IGetData 2     { 3         int GetData(int data); 4     } 5  6     public class Test : IGetData 7     { 8         public int GetData(int data) 9         {10             return data;11         }12     }

 假设正常情况下无法访问Test中的方法

  public class InvokeTestMember    {        private const BindingFlags flag = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public;        /// <summary>        /// 使用反射        /// </summary>        public  void InvokeByReflect()        {            Test obj = (Test)Activator.CreateInstance(typeof(Test));            MethodInfo mi = typeof(Test).GetMethod("GetData", flag);            object result = mi.Invoke(obj, new object[] { 10 });        }        /// <summary>        /// 使用委托        /// </summary>        public void InvokeByCreateDelegate()        {            Test obj = (Test)Activator.CreateInstance(typeof(Test));            MethodInfo mi = typeof(Test).GetMethod("GetData", flag);            Func<int, int> del = (Func<int, int>)Delegate.CreateDelegate(typeof(Func<int, int>), obj, mi);            object result = del(10);        }    }

现在来测试一下谁更快:

 1 class Program 2     { 3         static void Main(string[] args) 4         { 5             Go(); 6         } 7  8         static void Go() 9         {10             InvokeTestMember itm = new InvokeTestMember();11 12             Stopwatch sw = Stopwatch.StartNew();13             for (int i = 0; i < 1000 * 1000; i++)14             {15                 itm.InvokeByCreateDelegate();16             }17             Console.WriteLine("invokebydelegate: " + sw.Elapsed);18 19              sw = Stopwatch.StartNew();20             for (int i = 0; i < 1000 * 1000; i++)21             {22                 itm.InvokeByReflect();23             }24             Console.WriteLine("invokebyreflect: " + sw.Elapsed);25         }26     }

下面是输出结果:

有点意外啊,反射更快,至于是什么原因,大家去讨论一下吧,我现在也不是很清楚,有点复杂啊。。。。。。

当然了,还有更好的方法,速度更快,就是使用Dynamic关键字,此关键字在运行时跟object有点类似,它创建的对象只能在运行时去匹配相关的类型成员,所以有点类型不安全哦,下面是用dynamic关键字调用的方法,很简单:

  public void InvokeByDynamicKeyword()        {            dynamic obj = (Test)Activator.CreateInstance(typeof(Test));            object result = obj.GetData(10);        }

同样执行1000*1000次,它需要的时间如下:

当然了,我前面用到了接口,对于反射速度慢的最佳解决方案是,实现一个接口或一个抽象类,用他们的引用指向实现该接口的成员实例或继承该抽象类的成员实例,这是典型的插件编程模式,来看一下代码,很简单:

 public void InvokeByInterface()        {            IGetData obj = (IGetData)Activator.CreateInstance(typeof(Test));            object result = obj.GetData(10);        }

同样执行1000*1000次,它需要的时间如下:

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
深入反射生成数组的详解
浅谈.NET中的反射
C#中使用反射的性能分析-程序开发-红黑联盟
.Net 中的反射(动态创建类型实例)
数据生成器Bogus的使用以及基于声明的扩展
以非泛型方式调用泛型方法 (二)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服