mercredi 25 octobre 2017

How to create random data efficiently

I was creating random byte arrays to test some transport layer. I used to transport data created like this

 public byte[] Read(Data data) {
  var rnd = new Random();
  int size = data.ChunkSize;

  byte[] array = new byte[size];
  rnd.NextBytes(array);
  return array;
}

Because Read() is called many times, and creating a new byte array every time and filling it with random data could be slow, I wanted to come up with a solution, which doesn't use rnd.NextBytes in every call.

So I came up with a Class, which holds a static random array and reads from it. When it comes to the end of that array, it will start from the beginning again:

public class MyBuffer
{
private static readonly Random SRandom = new Random();

private readonly byte[] buffer = new byte[5000000]; // 5mb array with random data to read from
private int currentStart;

public MyBuffer()
{
  SRandom.NextBytes(buffer);
}

public IEnumerable<byte> Latest(int amountOfBytes)
{
  return FetchItems(amountOfBytes).ToArray();
}

private IEnumerable<byte> FetchItems(int amountOfBytes)
{
  IEnumerable<byte> fetchedItems = Enumerable.Empty<byte>();
  int total = 0;

  while (total < amountOfBytes)
  {
    int min = Math.Min(amountOfBytes, buffer.Length - currentStart);
    fetchedItems = fetchedItems.Concat(FetchItems(currentStart, min));

    total += min;
    currentStart += min;
    currentStart = currentStart % buffer.Length;
  }

  return fetchedItems;
}
private IEnumerable<byte> FetchItems(int start, int end)
{
  for (int i = start; i < end; i++)
  {
    yield return buffer[i];
  }
}
}

and the calling code looks like this:

private static readonly MyBuffer SBuffer = new MyBuffer();
private static byte[] array = new byte[0];

public byte[] Read(Data data) {

  int size = data.ChunkSize;

  if (array.Length != size)
  {
    array = new byte[size];
  }

  Array.Copy(SBuffer.Latest(size).ToArray(), array, size);
  return array;
}

But this turns out to be even slower (way slower) than my first attempt, and I can't really see why. Anyone can tell me where my code is inefficient or come up with any other efficient solution to my problem?

Thanks




Aucun commentaire:

Enregistrer un commentaire