Question

If you must pass a value type to a method, but for some reason, it must be passed as a reference type, is it faster to:

  1. Pass it as an object
  2. Pass is as a ValueType
  3. Pass it as a generic wrapper

I put some example code below to demonstrate exactly what I mean:.

public class Program
{
    public void Main()
    {
        var client = new IncrementedValueGetter();
        int i = 8675309;
        var byObject = client.IncrementObject(i);
        var byValueType = client.IncrementValueType(i);
        var byWrapper = client.IncrementWrapped(new ValueWrapper<int>(i));
    }
}
public class IncrementedValueGetter
{
    public int IncrementObject(object boxedValue)
    {
        return ((int)boxedValue) + 1;
    }
    public int IncrementValueType(ValueType boxedValueType)
    {
        return ((int) boxedValueType) + 1;
    }
    public int IncrementWrapped(ValueWrapper<int> valueWrapper)
    {
        return valueWrapper.Value + 1;
    }
}
public class ValueWrapper<T> 
    where T: struct
{
    private readonly T _value;
    public ValueWrapper(T value)
    {
        _value = value;
    }

    public T Value
    {
        get { return _value; }
    }
}
Was it helpful?

Solution

The first two are actually equivalent, and just generate the standard box IL. The third one requires the construction of your wrapper class, which is likely more expensive than the box call.

OTHER TIPS

The performance is probably comparable for all three since ultimately a value type must be represented in a reference type which means boxing at some point. But you can make things worse with unnecessary overhead and wrapping.

The important thing to realize about boxing is that it is not inherently expensive, it is only relatively expensive in context of something specific like boxing and unboxing in a tight loop. Try to focus on why you cannot use the the value type itself and why you need to use a reference type and let that guide your design. How would you like to access the value type from the reference type. Will the reference type hold other reference types? And so on.

Above all, if you're really concerned, just code it up and measure it. And keep measuring it in the context of your application, if it is performance critical, and you application evolves.

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