c#中關於sealed修飾類的性能提升的測試


  在clr var c#一書中,作者描述當用sealed修飾類時,可以提高系統性能而且建議大家也養成用sealed來修飾類的習慣。由於對性能二字比較敏感,所以本文先測試一下用sealed分別修飾和不修飾類時,new1億次的時間,然后說一下我的看法,如果有更好的測試方法,歡迎大家在此交流。

  首先上我的測試代碼:

    class Program
    {
        static void Main(string[] args)
        {
            for (int j = 0; j < 10; j++)
            {
                V t = new T();
                V u = new U();
                t.oo();
                u.oo();

                DateTime startTimeT = DateTime.Now;

                for (int i = 0; i < 100000000; i++)
                {
                    t.oo();
                }

                DateTime endTimeT = DateTime.Now;
                TimeSpan spanT = endTimeT - startTimeT;
                Console.WriteLine("not sealed class:" + spanT.Milliseconds.ToString());

                DateTime startTimeU = DateTime.Now;
                for (int i = 0; i < 100000000; i++)
                {
                    u.oo();
                }
                DateTime endTimeU = DateTime.Now;
                TimeSpan spanU = endTimeU - startTimeU;
                Console.WriteLine("sealed class:" + spanU.Milliseconds.ToString());
                Console.WriteLine();
            }
            Console.ReadKey();
        }
    }

    class T : V
    {
        public override string oo()
        {
             return "Hello Another";
        }
    }

    sealed class U:V
    {
        public override string oo()
        {
            return "Hello Another";
        }
    }

    class V
    {
        public virtual string oo()
        {
            return "Hello Another";
        }
    }

   運行結果:              

  結果讓我大吃一驚,用sealed修飾的類除了第一次快了2毫秒外,剩下九次結果都慢大約五六毫秒,為什么修飾完以后效率反而下降了呢。當用sealed修飾類以后, 1.有助於JIT內聯;2.消除了協變與逆變和后期綁定,使CLR直接執行這個實例。

  先說說“第1點”,促使JIT內聯代碼的因素有很多,JIT不會因為一個類是sealed,就去裝入其中的內容,而對於sealed類內部方法的內聯,很大原因也是由於方法槽映射關系決定的,sealed作用有待考證。

      第2點,由於sealed類不可派生或被繼承,所以的確在運行時省去可CLR一些額外的工作,但是這些工作只是一些類似於“尋址”的工作,因為虛擬方法表已經完成了運行時與編譯時的對應關系,純粹的運行時只是在尋找這些關系而已,所以sealed省去的只是一部分較為復雜的尋址關系,因為即使沒有繼承,也不可避免一個方法表的應用。(上述兩點參考http://kb.cnblogs.com/page/73598/)

  之所以CLR via C#一書中會這么寫,完全是因為作者本人的編程習慣。Jeffrey Richter不喜歡過分開放的對象,能private的絕對不public,除非確定要作為基類,不然一定會用sealed封死。

  寫到這里,我又忍不住多測了幾遍,發現有時候修飾候后慢50多毫秒(460 vs 410),結果證明不但沒快反而慢了好多,希望有知道原因的大牛指點一下^.^

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM