首页 > 解决方案 > c#:使用不安全指针在 double[] 数组和另一个不是 double[] 的数组之间复制

问题描述

我有一个相当奇怪的问题,我无法弄清楚。我正在使用创建缓冲区的第三方库。这个缓冲区可以包含双精度,但在双精度数组之间进行复制非常慢。特定数据类型的幕后一定有一些事情发生,特别是当您写入它时。例如,以下工作但需要超过 20 毫秒,而从双精度数组复制到另一个双精度数组需要 20 毫秒。

Mitov.SignalLab.RealBuffer mitovBuffer = new Mitov.SignalLab.RealBuffer(16384);
double[] doubleBuffer = new double[16384];

private void Test()
{
    for (int i=0; i < 16384; i++)
    {
         mitovBuffer[i] = doubleBuffer[i];
    }
}

这可行,但需要 20 多毫秒。我可以得到一个指向 mitovBuffer 的指针,并且我知道这个缓冲区中的每个“double”都存储了 8 个字节。有没有办法可以在这两者之间复制?我已经尝试了所有常见的东西,比如array.copy、块副本等。每次我得到一个无法从“double [] 转换为 double”的错误。谢谢,汤姆

标签: c#arraysunsafe-pointers

解决方案


也许这个函数很慢的一个原因是因为 Mitov.SignalLab.RealBuffer它是一个可调整大小的 delphi 缓冲区的包装器。如果我正确理解了他们的文档,那么您所做的逐字节分配涉及抽象层,甚至可能涉及调整每个字节的缓冲区大小。

API 甚至表示该类旨在用于 Delphi 代码,而不是其他语言。API 说

这是 Real(double) 数据包装缓冲区。使用此缓冲区从您的 Delphi 代码中访问和操作 Real(double) 数据。.NET、C++ Builder 和 Visual C++ 用户应该使用更方便、更强大的TSLCRealBuffer类。

但是,他们的公共 API 没有记录推荐的类。也许文档并不能真正反映产品,但如果我是你,我会打电话给他们的工程师,了解你打算做什么。由于您将无法固定它们的“缓冲区”抽象,我怀疑您不想使用非托管代码将字节推送到这些位置。

如果您想尝试按字节加载,也许您可​​以尝试他们记录的按字节方法:

function GetByteSize() : Cardinal - Returns the size of the buffer in bytes.
function GetSize() : Cardinal - Returns the size of the buffer in elements.
function ByteRead() : PByte
function ByteWrite() : PByte
function ByteModify() : PByte

或者也许您可以将您的数据转换为他们的内部格式,然后调用他们的公共程序procedure AddCustom(AData : ISLData)


推荐阅读