我应该通过ref传递IntPtr以获得更好的延迟吗?

时间:2013-08-04 09:48:04

标签: c# unmanaged

IntPtrstruct,因此默认情况下按值传递,这可能很昂贵(因为每次都会创建新对象),所以当新对象不是时,我们最好通过引用传递它强制性的。例如,我编写了这样的代码(请忽略硬编码的“幻数”):

    public static DateTime IntPtrToDateTime(ref IntPtr value, int offset)
    {
        short year = Marshal.ReadInt16(value, offset);
        byte month = Marshal.ReadByte(value, offset + 2);
        byte day = Marshal.ReadByte(value, offset + 3);
        byte hour = Marshal.ReadByte(value, offset + 4);
        byte minute = Marshal.ReadByte(value, offset + 5);
        byte second = Marshal.ReadByte(value, offset + 6);
        short msec = Marshal.ReadInt16(value, offset + 8);
        return new DateTime(year, month, day, hour, minute, second, msec);
    }

工作正常,但我怀疑我是否真的应该通过引用传递IntPtr?我猜IntPtr结构非常“轻”,可能很容易创建。

同样在.NET框架中的Marshal类中按值传递IntPtr,例如Marshal.ReadInt64我猜Marshal类被设计为可能性最小的延迟,但是那么为什么IntPtr没有通过引用传递?

  • 什么会更快 - 按值或按引用传递IntPtr?
  • 如果通过引用传递的速度更快,那么为什么Marshal类会按值传递IntPtr

2 个答案:

答案 0 :(得分:1)

结构按值传递,并且没有为它们分配新的堆对象。此外,IntPtr是CLR本身理解的类型。它是单个指针的大小。您应该期望获得与intlong相同的性能配置文件(具体取决于您的位数)。

通过引用传递它会减慢速度,因为你用指针包装一个指针。

答案 1 :(得分:1)

不,你不应该通过引用传递它。在这种情况下,这只会导致代码中的更多开销。

因为它是一个指针大小的结构,通过值和引用传递它会在堆栈上放入相同数量的数据,并且将它放在堆栈上的工作量相同。

然后使用通过引用传递的参数将导致另一个间接级别。您将从堆栈中读取指针,然后使用指针读取值,而不是从堆栈中读取值。

此外,对于您实际想要更改用于传递值的变量的参数,您应该只使用refout

如果由于性能原因而想要通过引用传递大型结构,那么实际上它本身就是导致性能问题的大型结构,而不是如何将其作为参数传递。你应该把它变成一个类,而不是改变你传递它的方式。