1

IntPtrは で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 を参照渡しする必要があるかどうかは疑問です。IntPtr構造体は非常に「軽量」で、おそらく非常に簡単に作成できると思います。

また、Marshal.NET フレームワークのクラスでは、 Marshal.ReadInt64IntPtrなどの値渡しが行われます。クラスは可能な限り低いレイテンシになるように設計されていると思いますが、なぜ参照渡しされないのでしょうか?MarshalIntPtr

  • IntPtr を値または参照で渡す方が速いでしょうか?
  • 参照渡しの方が速い場合、MarshalクラスがIntPtr値渡しするのはなぜですか?
4

2 に答える 2

1

いいえ、参照渡ししないでください。この場合、コードのオーバーヘッドが増えるだけです。

ポインターのサイズの構造体であるため、値渡しと参照渡しは同じ量のデータをスタックに置き、それをスタックに置くのはほぼ同じ量の作業になります。

ただし、参照によって渡されるパラメーターを使用すると、別のレベルの間接化が発生します。スタックから値を読み取る代わりに、スタックからポインターを読み取り、そのポインターを使用して値を読み取ります。

また、意味的には、値を渡すために使用される変数を実際に変更したいパラメーターに対してのみreforを使用する必要があります。out

パフォーマンス上の理由から参照渡ししたい大きな構造体がある場合、実際には大きな構造体自体がパフォーマンスの問題を引き起こしているのであって、パラメータとして渡す方法が原因ではありません。渡す方法を変更するのではなく、クラスにする必要があります。

于 2013-08-04T10:06:56.150 に答える
1

構造体は値によって渡され、構造体に割り当てられる新しいヒープ オブジェクトはありません。また、IntPtr は、CLR によってネイティブに認識される型です。1 つのポインターのサイズです。intまたはから期待できるのと同じパフォーマンス プロファイルを期待する必要がありlongます (ビット数によって異なります)。

ポインターをポインターでラップするため、参照で渡すと速度が低下します。

于 2013-08-04T09:50:53.973 に答える