装箱与拆箱的性能问题

来源:互联网 发布:php取出数组最大值 编辑:程序博客网 时间:2024/06/07 02:37

程序源码:

public class Program{static void Main(string[] args){Int32 v = 5;object o = v;v = 123;Console.WriteLine(v + ", " + (Int32)o);Console.ReadKey();}}

编码后的中间语言:
.method private hidebysig static void  Main(string[] args) cil managed{  .entrypoint  // 代码大小       53 (0x35)  .maxstack  3  .locals init (int32 V_0,           object V_1)  IL_0000:  nop  IL_0001:  ldc.i4.5  IL_0002:  stloc.0  IL_0003:  ldloc.0  IL_0004:  box        [mscorlib]System.Int32  IL_0009:  stloc.1  IL_000a:  ldc.i4.s   123  IL_000c:  stloc.0  IL_000d:  ldloc.0  IL_000e:  box        [mscorlib]System.Int32  IL_0013:  ldstr      ", "  IL_0018:  ldloc.1  IL_0019:  unbox.any  [mscorlib]System.Int32  IL_001e:  box        [mscorlib]System.Int32  IL_0023:  call       string [mscorlib]System.String::Concat(object,                                                              object,                                                              object)  IL_0028:  call       void [mscorlib]System.Console::WriteLine(string)  IL_002d:  nop  IL_002e:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()  IL_0033:  pop  IL_0034:  ret} // end of method Program::Main

可以看到:上述代码经过了3次装箱,1次拆箱;
字符串的 + 运算符,调用了Concat(Object arg0, Object arg1, Object arg2); 方法

优化后的写法:

Console.WriteLine(v + ", " + o);
中间语言:
.method private hidebysig static void  Main(string[] args) cil managed{  .entrypoint  // 代码大小       43 (0x2b)  .maxstack  3  .locals init (int32 V_0,           object V_1)  IL_0000:  nop  IL_0001:  ldc.i4.5  IL_0002:  stloc.0  IL_0003:  ldloc.0  IL_0004:  box        [mscorlib]System.Int32  IL_0009:  stloc.1  IL_000a:  ldc.i4.s   123  IL_000c:  stloc.0  IL_000d:  ldloc.0  IL_000e:  box        [mscorlib]System.Int32  IL_0013:  ldstr      ", "  IL_0018:  ldloc.1  IL_0019:  call       string [mscorlib]System.String::Concat(object,                                                              object,                                                              object)  IL_001e:  call       void [mscorlib]System.Console::WriteLine(string)  IL_0023:  nop  IL_0024:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()  IL_0029:  pop  IL_002a:  ret} // end of method Program::Main

这次经历了两次装箱。

进一步优化:

Console.WriteLine(v.ToString() + ", " + o);

中间语言:

.method private hidebysig static void  Main(string[] args) cil managed{  .entrypoint  // 代码大小       44 (0x2c)  .maxstack  3  .locals init (int32 V_0,           object V_1)  IL_0000:  nop  IL_0001:  ldc.i4.5  IL_0002:  stloc.0  IL_0003:  ldloc.0  IL_0004:  box        [mscorlib]System.Int32  IL_0009:  stloc.1  IL_000a:  ldc.i4.s   123  IL_000c:  stloc.0  IL_000d:  ldloca.s   V_0  IL_000f:  call       instance string [mscorlib]System.Int32::ToString()  IL_0014:  ldstr      ", "  IL_0019:  ldloc.1  IL_001a:  call       string [mscorlib]System.String::Concat(object,                                                              object,                                                              object)  IL_001f:  call       void [mscorlib]System.Console::WriteLine(string)  IL_0024:  nop  IL_0025:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()  IL_002a:  pop  IL_002b:  ret} // end of method Program::Main

我们写的代码只进行了一次装箱。

原创粉丝点击