如果我有一个字节数组并且想要转换该数组的连续 16 字节块,其中包含 .net 的表示形式Decimal
, 转化为适当的Decimal
struct,最有效的方法是什么?
在我正在优化的情况下,以下代码在我的分析器中显示为最大的 CPU 消耗者。
public static decimal ByteArrayToDecimal(byte[] src, int offset)
{
using (MemoryStream stream = new MemoryStream(src))
{
stream.Position = offset;
using (BinaryReader reader = new BinaryReader(stream))
return reader.ReadDecimal();
}
}
为了摆脱MemoryStream
and BinaryReader
,我想喂养一系列BitConverter.ToInt32(src, offset + x)
进入Decimal(Int32[])
构造函数会比我下面介绍的解决方案更快,但奇怪的是,下面的版本快两倍。
const byte DecimalSignBit = 128;
public static decimal ByteArrayToDecimal(byte[] src, int offset)
{
return new decimal(
BitConverter.ToInt32(src, offset),
BitConverter.ToInt32(src, offset + 4),
BitConverter.ToInt32(src, offset + 8),
src[offset + 15] == DecimalSignBit,
src[offset + 14]);
}
This is 速度提高 10 倍 as the MemoryStream/BinaryReader
组合,我用一堆极端值测试了它以确保它有效,但十进制表示并不像其他基本类型那样简单,所以我还不相信它适用于 100% 的可能十进制值。
然而从理论上讲,可能有一种方法可以将这 16 个连续字节复制到内存中的其他位置,并将其声明为 Decimal,而无需任何检查。有人知道这样做的方法吗?
(只有一个问题:虽然小数表示为 16 个字节,但某些可能的值并不构成有效的小数,因此进行未经检查的memcpy
可能会破坏东西......)
或者还有其他更快的方法吗?