1. 程式人生 > >裝箱與拆箱效能損耗詳解

裝箱與拆箱效能損耗詳解

拆箱是將引用型別轉換為值型別 ;反之,裝箱!

利用裝箱和拆箱功能,可通過允許值型別的任何值與Object 型別的值相互轉換,將值型別與引用型別連結起來 ;

例如: int val = 100; 
	    object obj = val; 
           Console.WriteLine (“物件的值 = ",obj); 

這是一個裝箱的過程,是將值型別轉換為引用型別的過程 

    int val = 100;
	object obj = val; 
	int num = (int) obj; 
	Console.WriteLine ("num: ",num);

這是一個拆箱的過程,是將值型別轉換為引用型別,再由引用型別轉換為值型別的過程

顯然,從原理上可以看出,裝箱時,生成的是全新的引用物件,這會有時間損耗,也就是造成效率降低。看下面程式碼

 class Program
    {
        static void Main(string[] args)
        {
            //// 用時:00:00:01.6070325(跟電腦執行效率有一定關係)
            //ArrayList list = new ArrayList();
            //Stopwatch watch = new Stopwatch();
            //watch.Start();
            //for (int i = 0; i < 10000000; i++)
            //{
            ////使用ArrayList集合,每次增加一個數字都會發生裝箱操作。
            //    list.Add(i);
            //}
            //watch.Stop();
            //Console.WriteLine(watch.Elapsed);
            //Console.ReadKey();/


            //用時:00:00:00.1402388,使用泛型集合後,省去了裝箱與拆箱操作,效能大大提升。
            List<int> list = new List<int>();
            Stopwatch watch = new Stopwatch();
            watch.Start();
            for (int i = 0; i < 10000000; i++)
            {
                list.Add(i);
            }
            watch.Stop();
            Console.WriteLine(watch.Elapsed);
            Console.ReadKey();
        }
    }

總結:

1.裝箱、拆箱必須是:值型別→引用型別  或  引用型別→值型別。

object,介面。值型別是可以實現介面。

Personp=new Student();//這個叫隱式型別轉換,不叫裝箱。

Studentstu=(Student)p;//這個叫顯示型別轉換,不叫拆箱。

int型別為什麼能裝箱到object型別,但不能裝箱到string型別或Person型別,

因為object型別時int型別的父類。

            2.拆箱時,必須用裝箱時的型別來拆箱

裝箱時如果是int,拆箱必須用int,不能用double

     3.方法過載時,如果具有該型別的過載,那麼就不叫拆箱或裝箱。 

  4.字串連線  

       string s1 = "a";
            string s2 = "b";
            int n3 = 10;
            double d4 = 99.9;
            string result = string.Concat(s1, s2, n3, d4);

//string.Concat(s1,s2, n3, d4); 判斷是否發生了裝箱,及次數。 

                           反編譯IL程式碼如下圖:   
 

可以得出發生了兩次裝箱吧。