小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

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

 昵稱10504424 2012-09-12

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

       有時候我們需要動態(tài)調(diào)用一個方法,到底用什么方法呢?很多人想到了反射,有的人也想到了委托。大家都知道反射很慢,因?yàn)榉瓷涞念愋筒话踩鸵詫ふ易址姆绞絹砥ヅ湎鄬?yīng)的成員,所以也有的人用委托,那到底誰更快呢?來看一個demo:

   

復(fù)制代碼
 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     }
復(fù)制代碼

 假設(shè)正常情況下無法訪問Test中的方法

復(fù)制代碼
  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);
        }
    }
復(fù)制代碼

現(xiàn)在來測試一下誰更快:

復(fù)制代碼
 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     }
復(fù)制代碼

下面是輸出結(jié)果:

有點(diǎn)意外啊,反射更快,至于是什么原因,大家去討論一下吧,我現(xiàn)在也不是很清楚,有點(diǎn)復(fù)雜啊。。。。。。

當(dāng)然了,還有更好的方法,速度更快,就是使用Dynamic關(guān)鍵字,此關(guān)鍵字在運(yùn)行時跟object有點(diǎn)類似,它創(chuàng)建的對象只能在運(yùn)行時去匹配相關(guān)的類型成員,所以有點(diǎn)類型不安全哦,下面是用dynamic關(guān)鍵字調(diào)用的方法,很簡單:

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

同樣執(zhí)行1000*1000次,它需要的時間如下:

當(dāng)然了,我前面用到了接口,對于反射速度慢的最佳解決方案是,實(shí)現(xiàn)一個接口或一個抽象類,用他們的引用指向?qū)崿F(xiàn)該接口的成員實(shí)例或繼承該抽象類的成員實(shí)例,這是典型的插件編程模式,來看一下代碼,很簡單:

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

同樣執(zhí)行1000*1000次,它需要的時間如下:

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多