Skip to content

Instantly share code, notes, and snippets.

@vangogih
Last active December 9, 2020 19:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vangogih/2e3585d15e09d6bfa5c1361099c827f0 to your computer and use it in GitHub Desktop.
Save vangogih/2e3585d15e09d6bfa5c1361099c827f0 to your computer and use it in GitHub Desktop.
Random benchmark
public class FastRandom : IRandom
{
public int Seed { get; private set; }
private const ulong Modulus = 2147483647; //2^31
private const ulong Multiplier = 1132489760;
private const double ModulusReciprocal = 1.0 / Modulus;
private ulong _next;
public FastRandom()
: this(DateTime.UtcNow.GetHashCode()) { }
public FastRandom(int seed)
{
NewSeed(seed);
}
public void NewSeed()
{
NewSeed(DateTime.UtcNow.GetHashCode());
}
/// <inheritdoc />
/// <remarks>If the seed value is zero, it is set to one.</remarks>
public void NewSeed(int seed)
{
if (seed == 0)
seed = 1;
Seed = seed;
_next = (ulong) seed % Modulus;
}
public float GetFloat()
{
return (float) InternalSample();
}
private double InternalSample()
{
var ret = _next * ModulusReciprocal;
_next = _next * Multiplier % Modulus;
return ret;
}
}
public interface IRandom
{
/// <returns>A random float number between 0.0f (inclusive) and 1.0f (inclusive)</returns>
float GetFloat();
}
public class RandomBenchmark : MonoBehaviour
{
public enum RandomType
{
fast,
system,
unity
}
public RandomType randomType = RandomType.fast;
public int resolution = 2048;
private IRandom _random;
private void Awake()
{
switch (randomType)
{
case RandomType.fast:
_random = new FastRandom();
break;
case RandomType.system:
_random = new SystemRandom();
break;
case RandomType.unity:
_random = new UnityRandom();
break;
default: throw new ArgumentOutOfRangeException();
}
StartBench();
}
public void StartBench()
{
var rnds = new float[resolution, resolution];
var watch = new Stopwatch();
var totalTime = 0L;
var iterations = 3;
for (var i = 0; i < iterations; i++)
{
watch.Start();
for (var x = 0; x < resolution; x++)
{
for (var y = 0; y < resolution; y++)
rnds[x, y] = _random.GetFloat();
}
watch.Stop();
totalTime += watch.ElapsedMilliseconds;
}
Debug.Log($"{_random.GetType().Name}|{totalTime / iterations}");
}
}
public class SystemRandom : Random, IRandom
{
public float GetFloat()
{
return (float) NextDouble();
}
}
public class UnityRandom : ITestRandom
{
public float GetFloat()
{
return Random.value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment