zoukankan      html  css  js  c++  java
  • 深入了解装箱和拆箱

     我们将通过实际的例子以及ILDASM.exe工具去查看装箱和拆箱的过程(至于ILDASM.EXE的用法请查看MicroSoft的帮助).

        一::我们想看下装箱和拆箱的对象

            装箱:值类型=>引用类型.

            拆箱:引用类型=>值类型

            所以我们看到再整个装箱和拆箱的过程中设计到两种类型.值类型(原类型(SbyteByteShortUshortIntUintLongUlongCharFloatDoubleBoolDecimal)、枚举(enum)、结构(struct).引用类型(类,接口,数组,委托,字符串等).

        实例1:阅读下面的程序,说出程序中的装箱和拆箱操作.

    using System;
    class sample1
    {
      
    public static void Main()
      {
        
    int i=10;
        
    object obj=i;
        Console.WriteLine(i
    +","+(int)obj);
      }

        答:实例1中进行了3次装箱和1次拆箱.第一次object obj=i;i装箱;而Console.WriteLine方法用的参数是String对象,因此,i+","+(int)obj中,i需要进行一次装箱(转换成String对象)(int)objobj对象拆箱成值类型,而根据WriteLine方法,比较将(int)obj值装箱成引用类型。说起来这么复杂,大家看看ildasm.exe的反汇编结果(如下图),数一下Box和Unbox就很容易理解了。


    如果我们将Console.WriteLine(i+","+(int)obj);改为:    Console.WriteLine(obj+","+obj); 得到同样的效果,而其中仅进行一次装箱操作(object obj=i;),虽然这个程序并没有实际的意义,但是加深我们对概念的理解。

       实例二:我这里我列出两个例子,装箱和拆箱对程序性能的影响

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Collections;

    namespace Boxandunbox
    {
        
    class Sample
        {
            
    public static void Main()
            {
                
    int count;
                DateTime startTime 
    = DateTime.Now;
                ArrayList myArrayList 
    = new ArrayList();

                
    // 重复5次测试
                for (int i = 5; i > 0; i--)
                {

                    myArrayList.Clear();
                    
    // 将值类型加入myArrayList数组
                    for (count = 0; count < 5000000; count++)
                        myArrayList.Add(count); 
    //装箱

                    
    // 重新得到值
                    int j;
                    
    for (count = 0; count < 5000000; count++)

                        j 
    = (int)myArrayList[count];  //拆箱
                }
                
    // 打印结果
                DateTime endTime = DateTime.Now;
                Console.WriteLine(
    "Start: {0}\nEnd: {1}\nSpend: {2}",
                startTime, endTime, endTime 
    - startTime);
                Console.WriteLine(
    "Push ENTER to return commandline");
                Console.ReadLine();
            }
        }
    }

    请看运行结果图

     

     

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Collections;

    namespace Boxandunbox
    {
        
    class Sample
        {
            
    public static void Main()
            {
                
    //Code1#region //Code1
                
    //int count;
                
    //DateTime startTime = DateTime.Now;
                
    //ArrayList myArrayList = new ArrayList();

                
    /**///// 重复5次测试
                //for (int i = 5; i > 0; i--)
                
    //{

                
    //    myArrayList.Clear();
                
    //    // 将值类型加入myArrayList数组
                
    //    for (count = 0; count < 5000000; count++)
                
    //        myArrayList.Add(count); //装箱

                
    //    // 重新得到值
                
    //    int j;
                
    //    for (count = 0; count < 5000000; count++)

                
    //        j = (int)myArrayList[count];  //拆箱
                
    //}
                /**///// 打印结果
                //DateTime endTime = DateTime.Now;
                
    //Console.WriteLine("Start: {0}\nEnd: {1}\nSpend: {2}",
                
    //startTime, endTime, endTime - startTime);
                
    //Console.WriteLine("Push ENTER to return commandline");
                
    //Console.ReadLine();
        #endregion
                
    int count;

                ArrayList myArrayList 
    = new ArrayList();

                
    // 构造 5000000 字符串数组
                string[] strList = new string[5000000];
                
    for (count = 0; count < 5000000; count++)
                    strList[count] 
    = count.ToString();

                
    // 重复5次测试
                DateTime startTime = DateTime.Now;
                
    for (int i = 5; i > 0; i--)
                {
                    myArrayList.Clear();
                    
    // 将值类型加入myArrayList数组
                    for (count = 0; count < 5000000; count++)
                        myArrayList.Add(strList[count]);
                    
    // 重新得到值
                    string s;
                    
    for (count = 0; count < 5000000; count++)
                        s 
    = (string)myArrayList[count];
                }
                
    // 打印结果
                DateTime endTime = DateTime.Now;
                Console.WriteLine(
    "Start: {0}\nEnd: {1}\nSpend: {2}",
                startTime, endTime, endTime 
    - startTime);
                Console.WriteLine(
    "Push ENTER to return commandline");
                Console.ReadLine();
            }
        }
    }

    结果如下图

     

    实例二说明:实例二(1)的循环中包含一次装箱和一次拆箱(这里我均忽略两个程序打印时的装箱操作),实例二(2)则没有相应的操作。当循环次数足够大的时候,性能差异是明显的。再次提醒你别忘了ILDASM.EXE这个工具哦,分别看看,才能一窥程序的本质。否则,粗看程序实例二(2)实例二(1)多了不少代码,更多了一个50000005M)的循环,就以为实例二(2)会更慢............
     

  • 相关阅读:
    mysql主从之过滤复制
    mysql主从之主从延时监控及原因分析
    mysql误删搭建有主从的主库master binlog处理
    mysql 主从复制原理,概念,故障的检控/分析/处理
    mysql之主从复制搭建
    mysql表的物理存储结构及逻辑结构
    sql语句执行过程及mysql权限管理
    linux安装mysql5.7.30 及配置多实例
    mysql备份恢复之xtrabackup (XBK、Xbackup)
    mysql 备份之逻辑备份mysqldump, mysqlbinlog, 全备及参数说明
  • 原文地址:https://www.cnblogs.com/purplefox2008/p/1808951.html
Copyright © 2011-2022 走看看