Fastest way to retrieve a variable-width integer chain from byte []

The name speaks for itself. I have a file containing base64 encoded byte[]variable width integer, min 8 bit, max 32bit

I have a large file (48 MB) and I'm trying to find the fastest way to capture integers from a stream.

This is the fastest code from the main application:

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();
}

I do not see a faster way to fill bytes up to 32 bits. Any ideas, guys or charts? Solutions should be in C #. I could fall into C / ++ if I should, but I don't want that.

+4
source share
3 answers

, . , , , , :

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;
}

. ! , , , .

+1

, . . , 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();
    }
0

, , 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();
    }
0

All Articles