在 C# 中将 Span 批量转换成基本数值
2021-03-13
现有 10000 个 double 数值以二进制编码的形式存储在 Span<byte> 中。怎样才能将其转换成 double[] (或者 Span<double>) 呢?
最傻瓜的方案
当然是循环使用 BitConverter 类的方法逐个转换。代码如下:
1 | private double[] ToDoubleArray(Span<byte> bytes) |
当然,可想而知,这种方法的性能非常一般。
无视类型复制
C/C++ 中的 memcopy() 等函数为我们提供了直接复制内存区域内容,而无视其类型属性的能力。而 .NET 中的 Buffer 类为我们提供了相似的方法。其中一个方法是 Buffer.BlockCopy().
如果源数据与程序运行平台的大小端属性一致的话,使用这一方法就可以快速地实现转换。
1 | private double[] ToDoubleArray(Span<byte> bytes) |
在本人测试中,这种方案与逐个转换的方案相比,可以带来 90% 以上的性能提升。不幸的是该方法目前只有接受数组的版本,因此在与 Span<byte> 配合使用时需要调用 ToArray() 方法。这将带来额外的内存开销。
不安全的复制
如果实际情况允许使用 unsafe 代码块,则可以使用 Buffer.MemoryCopy() 方法来省去将 Span<byte> 转换为数组的开销。需要注意的是,并非所有 .NET 语言均支持不安全代码。
1 | private double[] ToDoubleArray(Span<byte> bytes) |
使用这一方法与使用 BlockCopy() 方法相比,在执行时间方面没有明显的差异。但相比可以降低内存开销。