1

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

    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?我猜IntPtrstruct 非常“轻”并且可能很容易创建。

同样在Marshal.NET 框架中的类中IntPtr通过值传递,例如Marshal.ReadInt64我猜Marshal类被设计为尽可能低的延迟,但是为什么IntPtr不通过引用传递呢?

  • 什么会更快 - 通过值或引用传递 IntPtr?
  • 如果按引用传递更快,那么为什么MarshalIntPtr按值传递?
4

2 回答 2

1

不,您不应该通过引用传递它。在这种情况下,这只会给代码带来更多开销。

由于它是一个指针大小的结构,通过值和引用传递它会将相同数量的数据放入堆栈,并将其放入堆栈中的工作量大致相同。

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

此外,从语义上讲,您应该只将reforout用于您实际想要更改用于传递值的变量的参数。

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

于 2013-08-04T10:06:56.150 回答
1

结构是按值传递的,没有为它们分配新的堆对象。此外,IntPtr 是 CLR 原生理解的类型。它是单个指针的大小。您应该期待与intor相同的性能配置文件long(取决于您的位数)。

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

于 2013-08-04T09:50:53.973 回答