Question

I'm aware that boxing and unboxing are relatively expensive in terms of performance. What I'm wondering is:

Does passing a value type to a method's out parameter cause boxing/unboxing of the variable (and thus a performance hit)? Can the compiler optimize this away?

  int number;
  bool result = Int32.TryParse(value, out number);
Was it helpful?

Solution

As others have pointed out, there's no boxing here. When you pass a variable as an argument corresponding to an out or ref parameter, what you are doing is making an alias to the variable. You are not doing anything to the value of the variable. You're making two variables represent the same storage location.

Boxing only happens when a value of a value type is converted to a value of a reference type, and there's no conversion of any kind in your example. The reference type must of course be System.Object, System.ValueType, System.Enum or any interface. Usually it is pretty clear; there's an explicit or implicit conversion in the code. However, there can be circumstances where it is less clear. For example, when a not-overridden virtual method of a struct's base type is called, there's boxing. (There are also bizarre situations in which certain kinds of generic type constraints can cause unexpected boxing, but they don't usually come up in practice.)

OTHER TIPS

No boxing, compiler uses the ldloca.s instruction which pushes a reference to the local variable onto the stack (http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.ldloca_s(VS.71).aspx)

.method private hidebysig static void Func() cil managed
{
    .maxstack 2
    .locals init (
        [0] int32 num,
        [1] bool flag)
    L_0000: nop 
    L_0001: ldstr "5"
    L_0006: ldloca.s num
    L_0008: call bool [mscorlib]System.Int32::TryParse(string, int32&)
    L_000d: stloc.1 
    L_000e: ret 
}

No, there is no Boxing (required/involved).

When you do Box a variable, changes to the boxed instance do not affect the original. But that is exactly what out is supposed to do.

The compiler 'somehow' constructs a reference to the original variable.

There is no boxing; what the out parameter does is specifies that number must be assigned to within the TryParse method. Irrespective of this, it is still treated as an int, not an object.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top