我有一个大字节数组(大约50kb),我需要从中提取数值。每三个字节代表一个值。我试过的是使用LINQ跳过和获取,但是考虑到数组的大容量,这确实很慢。
这是我非常缓慢的例程:
List<int> ints = new List<int>();
for (int i = 0; i <= fullFile.Count(); i+=3)
{
ints.Add(BitConverter.ToInt16(fullFile.Skip(i).Take(i + 3).ToArray(), 0));
}
我认为我对此有错误的处理方法。
您的代码
首先,ToInt16
仅使用两个字节。因此,您的第三个字节将被丢弃。
您不能使用ToInt32
,因为它会包含一个额外的字节。
让我们回顾一下:
fullFile.Skip(i).Take(i + 3).ToArray()
..并仔细查看Take(i + 3)
。它说您要复制越来越大的缓冲区。例如,当i
在索引32000上时,您将32003字节复制到新缓冲区中。
这就是代码很慢的原因。
代码也很慢,因为您分配了很多字节缓冲区,这些字节缓冲区需要进行垃圾回收。
一个更好的解决方案
因此,最有效的方法是由您自己进行转换(移位)。>>
类似:
List<int> ints = new List<int>(); for (int i = 0; i <= fullFile.Length; i += 3) { // This code assume little endianess var value = (fullFile[i + 2] << 16) + (fullFile[i + 1] << 8) + fullFile[i]; ints.Add(value); }
此代码不分配任何额外的内容(int除外),并且应该相当快。
您可以在MSDN中阅读有关Shift operators的更多信息。关于endianess