From cade17a9a65f04cb80692bbf2ef143fe88880381 Mon Sep 17 00:00:00 2001 From: Joseph Montanaro Date: Sun, 18 Jul 2021 22:07:37 -0700 Subject: [PATCH] initial implementation --- fastrand.nim | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 fastrand.nim diff --git a/fastrand.nim b/fastrand.nim new file mode 100644 index 0000000..9480411 --- /dev/null +++ b/fastrand.nim @@ -0,0 +1,52 @@ +import random, math +import times, std/monotimes, strformat, strutils + + +proc formatNum(n: SomeNumber): string = + let s = $(n.round) + let t = s[0 .. s.len - 3] + var count = 1 + for i in countdown(t.high, 0): + result.insert($t[i], 0) + if count mod 3 == 0 and i != 0: + result.insert(",", 0) + count += 1 + + +proc formatRate(n: Natural, d: Duration): string = + result = formatNum(1_000_000'f64 * n.float64 / d.inMicroseconds.float64) + + +proc fastRand(r: var Rand, x: Natural): uint64 = + # return ((r.next shr 32) * x.uint64) shr 32 + let x = x.uint64 + if x <= (uint64.high shl 32): + return ((r.next shr 32) * x.uint64) shr 32 + else: + return r.next mod x.uint64 + + +proc testFastRand(num = 1_000_000_000): Duration = + var r = initRand(rand(int64)) + let start = getMonoTime() + for i in 1 .. num: + discard r.fastRand(5) + result = getMonoTime() - start + # echo "fastrand execution rate: ", 1000 * num / dur.inMilliseconds.int, " generated per second." + + +proc testStdRand(num = 1_000_000_000): Duration = + var r = initRand(rand(int64)) + let start = getMonoTime() + for i in 1 .. num: + discard r.rand(4) + result = getMonoTime() - start + # echo "std rand execution rate: ", 1000 * num / dur.inMilliseconds.int, " generated per second." + + +randomize() +let runs = 100_000_000 +let fr = testFastRand(runs) +echo "fastrand execution rate: ", formatNum(1_000_000 * runs / fr.inMicroseconds.int) +let sr = testStdRand(runs) +echo "standard execution rate: ", formatNum(1_000_000 * runs / sr.inMicroseconds.int)