patterncsharpMinor
Using pointers and type cast to break up integers into byte array
Viewed 0 times
arrayintobytecasttypeusingpointersandintegersbreak
Problem
Usually I don't start using pointers for a few microseconds here and there.
But with this implementation I started getting results of factor 2.
Now essentially I need to put the 32bit integers I get from Random.Next into a byte array.
I started implementing the randomizer as
Thats why I got the size in the signature and th
But with this implementation I started getting results of factor 2.
using System;
class BenchmarkPointers {
public static void Main() {
#if ALLOW_UNSAFE
Console.WriteLine("This is safe code");
#else
Console.WriteLine("This is unsafe code");
#endif
int bs = 0x100000;
byte[] buffer = new byte[bs];
Random rnd = new Random(DateTime.Now.GetHashCode());
long total = 0;
long avg = 0;
int max = 100;
DateTime start = DateTime.Now;
for(int i = 0; i <= max; i++) {
start = DateTime.Now;
RandomizeBuffer(ref buffer, bs, rnd);
TimeSpan ts = DateTime.Now - start;
total += (long)ts.TotalMilliseconds;
Console.WriteLine("Pass {0} took {1} ms", i, ts.TotalMilliseconds);
}
avg = total / max;
Console.WriteLine("Avarage time for one pass was: {0}ms\nTotal time over {1} passes was {2}ms", avg, max, total);
}
public static
#if ALLOW_UNSAFE
unsafe
#endif
void RandomizeBuffer(ref byte[] buffer, int bufferSize, Random rnd) {
#if ALLOW_UNSAFE
fixed(byte * pBuffer = buffer)
#endif
for(int i = 0; i < bufferSize; i += 4) {
int k = rnd.Next(int.MinValue, int.MaxValue);
#if ALLOW_UNSAFE
// One of the rare moments when I like to use pointers (with type casting)
*((int*)(pBuffer + i)) = k;
#else
byte[] bits = BitConverter.GetBytes(k);
buffer[i ] = bits[0];
buffer[i + 1] = bits[1];
buffer[i + 2] = bits[2];
buffer[i + 3] = bits[3];
#endif
}
}
}Now essentially I need to put the 32bit integers I get from Random.Next into a byte array.
I started implementing the randomizer as
unsafe void RandomizeBuffer(byte **pBuffer, int bufferSize, Random rnd)Thats why I got the size in the signature and th
Solution
If the buffer size is not divisible by 4, the remaining bytes are not set. This is a bug and should be corrected.
If you just need random values in the bytes, Random.NextBytes() does what you are trying to do and will likely be faster than both of your current implementation. It's up to you to decide if you care that the values were technically int32's before being written to the buffer.
When writing a benchmark, Stopwatch will provide more precision than
It is probably best to take the seed from a command line argument. This will allow you to remove one more variable between the two implementation. While I don't expect
Arrays have a
As for if it is worth it to make this optimization, that isn't something we can tell you. Have you profiled the execution of the actual program? Is this where your code if spending the majority of it's time? If it's actually IO bound, ~12ms doesn't mean anything. Where as, if this chunk of code is running millions of times each time your program does a single task, ~12ms is huge and well worth optimizing.
If you just need random values in the bytes, Random.NextBytes() does what you are trying to do and will likely be faster than both of your current implementation. It's up to you to decide if you care that the values were technically int32's before being written to the buffer.
When writing a benchmark, Stopwatch will provide more precision than
DateTime.Now. I also thing 100 is not a large enough number of iterations to get a good average. As you pointed out, there were outliers that took almost twice as long as the majority of values.It is probably best to take the seed from a command line argument. This will allow you to remove one more variable between the two implementation. While I don't expect
Random's execution time to change significantly based on the seed, it is best to keep everything else equal when comparing two things.Arrays have a
Length property, so you shouldn't be dealing with the buffer size independently.As for if it is worth it to make this optimization, that isn't something we can tell you. Have you profiled the execution of the actual program? Is this where your code if spending the majority of it's time? If it's actually IO bound, ~12ms doesn't mean anything. Where as, if this chunk of code is running millions of times each time your program does a single task, ~12ms is huge and well worth optimizing.
Context
StackExchange Code Review Q#134882, answer score: 8
Revisions (0)
No revisions yet.