如何在C#/ .NET中将值类型作为引用类型传递时获得最佳性能?

时间:2011-05-13 02:23:45

标签: c# .net performance boxing unboxing

如果必须将值类型传递给方法,但由于某种原因,它必须作为引用类型传递,它是否更快:

  1. 将其作为object
  2. 传递
  3. 传递为ValueType
  4. 将其作为通用包装器传递
  5. 我在下面放了一些示例代码来说明我的意思:。

    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; }
        }
    }
    

2 个答案:

答案 0 :(得分:4)

前两个实际上是等价的,只生成标准box IL。第三个需要构造你的包装类,这可能比盒子调用更昂贵。

答案 1 :(得分:1)

性能可能与所有三者相当,因为最终值类型必须以引用类型表示,这意味着在某些时候装箱。但是你可以通过不必要的开销和包装使事情变得更糟。

关于拳击的重要之处在于它本身并不昂贵,它只是在特定的情况下相对昂贵,如拳击和拆箱在紧密的循环中。尝试关注为什么不能使用值类型本身以及为什么需要使用引用类型并指导您的设计。您希望如何从引用类型访问值类型。引用类型是否包含其他引用类型?等等。

最重要的是,如果你真的担心,只需编码并测量它。并且在应用程序的上下文中继续测量它,如果它对性能至关重要,那么应用程序就会发展。