Volví a implementar Math.random() usando crypto.getRandomValues con un esquema de "grupo de entropía" para reducir la sobrecarga de las llamadas a crypto.getRandomValues . En mi computadora (x86_64 Windows Chrome) esto parece ser un 260% más rápido que Math.random() . Encuentro esto sorprendente porque tenía la impresión de que Chrome implementa este último usando el increíblemente rápido xorshift128+ PRNG, que debería ser mucho más rápido que cualquier CSPRNG que se esté usando debajo del capó para el primero.
class EntropyPool { #entropy; #index constructor(poolSize = 1024) { this.#entropy = new Uint32Array(poolSize) this.#index = 0 crypto.getRandomValues(this.#entropy) } next() { const value = this.#entropy[this.#index++] if (this.#index === this.#entropy.length) { crypto.getRandomValues(this.#entropy) this.#index = 0 } return value } } const pool = new EntropyPool() function random() { return pool.next() / 4294967296 }