我有一个类将在整个应用程序期间持续存在一些实例。这些对象都需要调用一个 dll 方法,该方法从现有的 float[] 缓冲区中附加数据,并将完整的数据集传递给一个接受 IntPtr(浮点数组)的 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 的大小?