dtl-js
Version:
Data Transformation Language - JSON templates and data transformation
59 lines (46 loc) • 1.77 kB
JavaScript
const { performance } = require('perf_hooks');
const crypto = require('crypto');
let getRandomValues = crypto.webcrypto.getRandomValues.bind(crypto.webcrypto);
function random_number_up_to_rejection(max) {
if (max <= 0 || max > 0xFFFFFFFF) {
throw new RangeError('max must be between 1 and 2^32-1');
}
const value_array = new Uint32Array(1);
const max_acceptable_value = Math.floor((0xFFFFFFFF + 1) / max) * max - 1;
let result;
do {
getRandomValues(value_array);
result = value_array[0];
} while (result > max_acceptable_value);
return result % max;
}
function random_number_up_to_batch(max) {
if (max <= 0 || max > 0xFFFFFFFF) {
throw new RangeError('max must be between 1 and 2^32-1');
}
const value_array_size = 128; // Size of the array to generate random values
const value_array = new Uint32Array(value_array_size);
const max_acceptable_value = Math.floor((0xFFFFFFFF + 1) / max) * max - 1;
while (true) {
getRandomValues(value_array);
for (let i = 0; i < value_array.length; i++) {
if (value_array[i] <= max_acceptable_value) {
return value_array[i] % max;
}
}
}
}
function benchmark(func, max, iterations) {
const start = performance.now();
for (let i = 0; i < iterations; i++) {
func(max);
}
const end = performance.now();
return end - start;
}
const max = 250000;
const iterations = 500000;
const timeRejection = benchmark(random_number_up_to_rejection, max, iterations);
console.log(`Rejection Sampling: ${timeRejection} ms`);
const timeBatch = benchmark(random_number_up_to_batch, max, iterations);
console.log(`Batch Generation: ${timeBatch} ms`);