0

アプリケーションの期間中、いくつかのインスタンスが持続するクラスがあります。これらのオブジェクトはそれぞれ、既存の float[] バッファからデータを追加する dll メソッドを呼び出し、完全なデータセットを IntPtr (float 配列) を受け入れる DLL メソッドに毎秒数回渡す必要があります。アンマネージ コードとして実行する方がよいでしょうか:



    class PersistentThing : IDisposable {
        readonly IntPtr _floats = Marshal.AllocHGlobal(sizeof(float) * ArraySize);

        public void DoFrequentAction() {
            // Append data from a buffer to the memory space.
            var floatOffsetPtr = new IntPtr(_floats.ToInt32() + _floatsIndex * sizeof(float));
            Marshal.Copy(_buffer, _bufferIndex, floatOffsetPtr, _bufferCount);

            // Call a DLL method with with memory pointer
            CallDllMethod(_floats);
        }

        // Need to dispose the unmanaged memory
        public void Dispose() {
            Marshal.FreeHGlobal(_floats);
        }
    }

または、安全でないタグを使用して修正した方がよいでしょうか?


    class PersistentThing2 {
        readonly float[] _floats = new float[ArraySize];

        public unsafe void DoFrequentAction() {
            // Append data from a buffer to the memory space.
            Array.Copy(_buffer, _bufferIndex, _floats, _floatsIndex, _bufferCount);

            // Call a DLL method with with memory pointer
            fixed (float* floatsPtr = _floats) {
                CallDllMethod((IntPtr)floatsPtr);
            }
        }
    }

コンパイラで「安全でない」タグを使用する必要がないという利点はありますか? マーシャルクラスは実際に「より安全」ですか? これらの方法のうち、一般的にパフォーマンスが優れているのはどれですか?

私が前者に傾いているのは_floats、メモリ空間をクリーンアップするときに GC が (非常に大きくなる可能性がある) 心配する必要がないからです。それは合理的な懸念ですか?推奨事項は ArraySize のサイズに依存しますか?

4

2 に答える 2

3

どちらの場合も、安全でないネイティブ コードを呼び出しています。

私は 2 番目のオプションを好みます。よりクリーンで、理解しやすく、より明白です。また、配列を収集するために IDisposable を強制することもありません。

于 2009-11-05T18:59:24.133 に答える
2

最終的に、両方のソリューションが問題ないことを知りました。パフォーマンスはほぼ同じであり、GC は 2 番目のソリューションに影響を与えません。これは、オブジェクトがラージ オブジェクト ヒープに割り当てられて移動されないか、ガベージ コレクターですぐに第 2 世代に昇格されてほとんど移動されないためです。 .

于 2009-11-16T17:38:25.157 に答える