关于装箱拆箱为什么会影响效率

  • 概念
  • 示例
    • 装箱
    • 拆箱
  • 结论

概念

  • 装箱值类型引用类型转换时发生,在中分配。
  • 拆箱引用类型值类型转换时发生。

示例

装箱

        public void BoxIn()
        {
            object tempObj = 4;
        }

示意:将整型常量1赋给object类型的变量obj;值类型是要放在上的,而object是引用类型,它需要放在上;要把值类型放在上就需要执行一次装箱操作。

  • 利用ildasm 查看IL代码
    .method public hidebysig instance void  BoxIn() cil managed
    {
      // Code size       8 (0x8)
      .maxstack  2
      .locals init (object V_0)/*声明object类型的名称为objValue的局部变量 */
      IL_0000:  ldc.i4.4 /*小于8大于0的情况下用的是ldc.i4 num ,而大于8 和小于0又是针对32位(在64 位下还有ldc.i8 num )的机器编程就用 ldc.i4.s num */;
      IL_0001:  box        [mscorlib]System.Int32  /*执行IL box指令,在内存堆中申请System.Int32类型需要的堆空间*/
      IL_0006:  stloc.0 /*弹出堆栈上的变量,将它存储到索引为0的局部变量中*/
      IL_0007:  ret
    } // end of method Test::BoxIn

拆箱

        public void BoxOut()
        {
            object tempObj = 9;
            int tempInt = (int)tempObj;
        }

示意:首先进行一次装箱操作将整形数字装箱引用类型;然后又执行一次拆箱操作,将存储到上的引用变量tempObj存储到局部整形值类型变量tempInt 中。

  • 同理利用ildasm 查看IL代码
    .method public hidebysig instance void  BoxOut() cil managed
    {
      // Code size       16 (0x10)
      .maxstack  2
      .locals init (object V_0,
               int32 V_1)
      IL_0000:  ldc.i4.s   9
      IL_0002:  box        [mscorlib]System.Int32
      IL_0007:  stloc.0 /*运行原理同上*/
      IL_0008:  ldloc.0 /*将索引为0的局部变量(即tempObj变量)压入栈*/
      IL_0009:  unbox.any  [mscorlib]System.Int32 /*执行拆箱指令将引用类型object转换成System.Int32类型*/
      IL_000e:  stloc.1/*将栈上的数据存储到索引为1的局部变量即tempInt*/
      IL_000f:  ret
    } // end of method Test::BoxOut

结论

可见,执行装箱操作时不可避免的要在上申请内存空间,并将堆栈上的值类型数据复制到申请的内存空间上,因此消耗内存cpu资源。可以用泛型来解决这问题。

你可能感兴趣的:(学习手记)