在 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()
方法相比,在执行时间方面没有明显的差异。但相比可以降低内存开销。