24

I am using this:

byte[] buffer = new byte[10240];

As I understand this initialize the buffer array of 10kb filled with 0s.

Whats the fastest way to fill this array (or initialize it) with junk data every time?

I need to use that array like >5000 times and fill it every time with different junk data, that's why I am looking for a fast method to do it. The array size will also have to change every time.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
flyout
  • 497
  • 1
  • 9
  • 16
  • 6
    Do the junk data need to be random? Or just different each time? – Dirk Vollmar Jun 06 '10 at 17:47
  • 1
    Please don't duplicate tags ("C#") in the title. Also, do not use "csharp" as a tag. The fact that it's only used in 4 questions should be a clue to you to not use it. – John Saunders Jun 06 '10 at 19:05

5 Answers5

47

Answering 'the fastest way' is impossible without describing what the properties of your junk data have to be. Why isn't all zeroes valid junk data?

That said, this is a fast way to fill your array with meaningless numbers.

Random r = new Random();
r.NextBytes(buffer);

You might also look at implementing your own Linear congruential generator if Random isn't fast enough for you. They're simple to implement and fast, but won't give high quality random numbers. (It's unclear to me if you need those or not.)

Joren
  • 14,472
  • 3
  • 50
  • 54
14

If you are happy with the data being random, but being created form a random seed buffer, then you could do the following:

public class RandomBufferGenerator
{
    private readonly Random _random = new Random();
    private readonly byte[] _seedBuffer;

    public RandomBufferGenerator(int maxBufferSize)
    {
        _seedBuffer = new byte[maxBufferSize];

        _random.NextBytes(_seedBuffer);
    }

    public byte[] GenerateBufferFromSeed(int size)
    {
        int randomWindow = _random.Next(0, size);

        byte[] buffer = new byte[size];

        Buffer.BlockCopy(_seedBuffer, randomWindow, buffer, 0, size - randomWindow);
        Buffer.BlockCopy(_seedBuffer, 0, buffer, size - randomWindow, randomWindow);

        return buffer;
    }
}

I found it to be approx 60-70 times faster then generating a random buffer from scratch each time.

              START: From seed buffer.
00:00:00.009  END  : From seed buffer. (Items = 5,000; Per Second = 500,776.20)
              START: From scratch.
00:00:00.604  END  : From scratch. (Items = 5,000; Per Second = 8,276.95) 

Update

The general idea is to create a RandomBufferGenerator once, and then use this instance to generate random buffers, e.g.:

RandomBufferGenerator generator = new RandomBufferGenerator(MaxBufferSize);

byte[] randomBuffer1 = generator.GenerateBufferFromSeed(10 * 1024);
byte[] randomBuffer2 = generator.GenerateBufferFromSeed(5 * 1024);
...
Tim Lloyd
  • 37,954
  • 10
  • 100
  • 130
  • I understand that to use that code I should do: RandomBufferGenerator bufferGenerator = new RandomBufferGenerator(1024); byte[] buffer = bufferGenerator.GenerateBufferFromSeed(1024); But should I create a RandomBufferGenerator instance everytime? Could you give me an example of how to use it? Thanks. – flyout Jun 06 '10 at 18:51
  • Yes, create the RandomBufferGenerator once and then use this instance to generate your buffers. I have updated the answer with some example usage. – Tim Lloyd Jun 06 '10 at 19:03
  • 5
    Never, ever use this code: `new Random(DateTime.Now.Millisecond)` - when you simply use `new Random` it automatically seeds the value to the current tick (100 nanoseconds) from `Environment.TickCount`. In your code, all `Random` s instantiated in the same millesecond would have the same seed so produce the same numbers and in that time frame thousands could be created. It just isn't good practice. – Callum Rogers Jun 06 '10 at 19:09
  • 3
    @Callum Rogers: The instance is intended to be re-used, so for this purpose it is fine. Whilst you have a general valid point, it does not apply here. – Tim Lloyd Jun 06 '10 at 19:11
  • Thank you VERY much chibacity, your code works a LOT faster than .NextBytes – flyout Jun 06 '10 at 22:28
3

Look at the System.Random.NextBytes() method

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
3

As another option to consider, Marshall.AllocHGlobal will allocate unmanaged memory. It doesn't zero out the memory, you get what happened to be there so it's very fast. Of course you now have to work with this memory using unsafe code, and if you need to pull it into the managed space you are better off with Random.NextBytes.

Matt Greer
  • 60,826
  • 17
  • 123
  • 123
  • Or open an random image/file/the executable and simply use that as random data. – CodingBarfield Jan 10 '12 at 14:36
  • 1
    I'm pretty sure this is what the OP was really asking for. Essentially, declaring char* in unsafe code to point to an uninitialized chunk of memory filled with whatever was there last. – Chris Moschini Jun 14 '12 at 07:56
1

How junky should be the data? Do you mean random? If that is the case just use the Random class.

Petar Minchev
  • 46,889
  • 11
  • 103
  • 119
  • Yes I mean random data, NextBytes looks good I will test it in a while, thanks everyone for the replies. – flyout Jun 06 '10 at 17:56