我使用crypto.getRandomValues
重新实现了Math.random()
,并采用了“熵池”方案来减少调用crypto.getRandomValues
的开销。在我的电脑(x86_64 Windows Chrome)上,这似乎比Math.random()
快260%。我觉得这很令人惊讶,因为我的印象是Chrome使用非常快的xorshift128+ PRNG实现了后者,这应该比前者使用的CSPRNG快几个数量级。
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
}
1条答案
按热度按时间i2byvkas1#
(V8开发者在这里)。
最常见的陷阱之一是不使用测试操作的结果,这允许优化编译器优化死代码,并且您将留下测量(几乎)空循环。有时这只适用于您正在比较的变量之一,这将产生严重的偏差结果。
如果通过将测试更改为强制使用结果:
然后你会看到
Math.random
实际上比你的定制random
快(我看到的是642K vs 507K ops/sec)。换句话说:这个问题的前提是不正确的,
Math.random
* 不 * 被crypto.getRandomValues
超越。只是微基准测试使用后者的特定方式在结果不被使用时更适合于死代码消除。