I have a class that will have a few instances persistent throughout the duration of the application. These objects will each need to call a dll method that appends data from an existing float[] buffer, and passes the full dataset to a DLL method that accepts an IntPtr (float array), several times per second. Is it better to do it as unmanaged code:
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);
}
}
or would it be better to use an unsafe tag and fixed?
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);
}
}
}
Is there any advantage of not having to use the "unsafe" tag in the compiler? Is the Marshal class actually any "safer"? Which of these methods generally have the better performance?
I lean toward the former, just because that way the GC doesn't have to worry about _floats
(which could be quite large) when cleaning up the memory space. Is that a reasonable concern? Does the recommendation depend on the size of ArraySize?