Compare Math.random() to Xoshiro128(*) (v4)

Revision 4 of this benchmark created on


Description

This is a bastardized version of Xoshiro128++ It has been butchered to work with Javascript 32 bit numbers. See the source for better and more correct ideas: https://prng.di.unimi.it/

Note: extra HTML (and code) is to prevent "dead code elimination" and encourage realistic optimization from the JavaScript VM.

Preparation HTML

<p id="acc"></p>

Setup

// Xoshiro128(*)
var rotl32 = (x, k) => (x << k) & 0xFFffFFff | (x >>> (32 - k));
var s128 = new Uint32Array([
  0xc0220938,
  0xe445bfa6,
  0x921e3fc0,
  0x9d720779,
]);

function next32() {
  const s0 = s128[0];
  const s3 = s128[3];
 	const result = rotl32(s0 + s3, 23) + s0 & 0xFFffFFff;

	const t = s128[1] << 9;

	s128[2] ^= s128[0];
	s128[3] ^= s128[1];
	s128[1] ^= s128[2];
	s128[0] ^= s128[3];

	s128[2] ^= t;
	s128[3] = rotl32(s128[3], 17);

	return result;
}

function randRange64k(max) {
  return ((next32() & 0xFFff) * max) >>> 16;  // safe for 0 <= max <= 64k
}
// other setup
var numLoop = 16384;
var maxInt = 53876;
function update(a, b) {
	return (b - a) / 2.0;
}
function finish(acc) {
	let elem = document.getElementById("acc");
	elem.innerText = acc;
}

Test runner

Ready to run.

Testing in
TestOps/sec
Math.random()
let acc = 0.0;
for (let i = 0; i < numLoop; i++) {
  let res = Math.floor(Math.random() * maxInt);
  acc += update(res, acc);
}
finish(acc);
ready
Xoshiro128(*)
let acc = 0.0;
for (let i = 0; i < numLoop; i++) {
  let res = randRange64k(maxInt);
  acc += update(res, acc);
}
finish(acc);
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.