[英]Fastest way to extract variable width signed integer from byte[]
標題不言而喻。 我有一個文件,包含一個base64編碼的byte[]
,可變寬度整數,最小8位,最大32位
我有一個大文件(48MB),我試圖找到從流中抓取整數的最快方法。
這是perf應用程序中最快的代碼:
static int[] Base64ToIntArray3(string base64, int size)
{
List<int> res = new List<int>();
byte[] buffer = new byte[4];
using (var ms = new System.IO.MemoryStream(Convert.FromBase64String(base64)))
{
while(ms.Position < ms.Length)
{
ms.Read(buffer, 0, size);
res.Add(BitConverter.ToInt32(buffer, 0));
}
}
return res.ToArray();
}
我看不到更快的方法將字節填充到32位。 任何想法,破壞和chapettes? 解決方案應該在c#中。 如果我必須但我不想,我可以淪為C / ++。
沒有理由使用內存流將字節從數組移動到另一個數組,只需直接從數組中讀取。 此外,數組的大小是已知的,因此需要將項添加到列表然后轉換為數組,您可以從頭開始使用數組:
static int[] Base64ToIntArray3(string base64, int size) {
byte[] data = Convert.FromBase64String(base64);
int cnt = data.Length / size;
int[] res = new int[cnt];
for (int i = 0; i < cnt; i++) {
switch (size) {
case 1: res[i] = data[i]; break;
case 2: res[i] = BitConverter.ToInt16(data, i * 2); break;
case 3: res[i] = data[i * 3] + data[i * 3 + 1] * 256 + data[i * 3 + 2] * 65536; break;
case 4: res[i] = BitConverter.ToInt32(data, i * 4); break;
}
}
return res;
}
注意:未經測試的代碼! 你必須驗證它實際上做了它應該做的事情,但至少它顯示了原理。
這可能是我會這樣做的。 不使用流應該可以提高性能。 這似乎是使用Linq應該很容易做的事情,但我無法弄明白。
static int[] Base64ToIntArray3(string base64, int size)
{
if (size < 1 || size > 4) throw new ArgumentOutOfRangeException("size");
byte[] data = Convert.FromBase64String(base64);
List<int> res = new List<int>();
byte[] buffer = new byte[4];
for (int i = 0; i < data.Length; i += size )
{
Buffer.BlockCopy(data, i, buffer, 0, size);
res.Add(BitConverter.ToInt32(buffer, 0));
}
return res.ToArray();
}
好的,我相信這是Linq的方法:
static int[] Base64ToIntArray3(string base64, int size)
{
byte[] data = Convert.FromBase64String(base64);
return data.Select((Value, Index) => new { Value, Index })
.GroupBy(p => p.Index / size)
.Select(g => BitConverter.ToInt32(g.Select(p => p.Value).Union(new byte[4 - size]).ToArray(), 0))
.ToArray();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.