Java中的快速实值随机生成器

2022-09-03 09:16:33

java.util.Random.nextDouble()对我来说很慢,我需要一些非常快的东西。

我做了一些谷歌搜索,我只发现基于整数的快速随机生成器。这里有来自区间<0,1)的实数吗?


答案 1

如果你需要一些快速的东西并可以访问Java8,我可以推荐SplittableRandom。它更快(大约是两倍),并且具有更好的统计分布。java.utils

如果你需要一个更快或更好的算法,我可以推荐这些专门的XorShift变体之一:

有关这些算法及其质量的信息可以在这个大型PRNG比较中找到。

我做了一个独立的性能比较,你可以在这里找到详细的结果和代码:github.com/tobijdc/PRNG-Performance

此外,Apache Commons RNG对其所有已实现的算法进行了性能测试

断续器

切勿使用 ,请使用 。如果您需要更快或更好的PRNG,请使用XorShift变体。java.util.Randomjava.util.SplittableRandom


答案 2

您可以通过以下方式修改基于整数的 RNG,以在区间 [0,1) 中输出双精度值:

double randDouble = randInt()/(RAND_INT_MAX + 1.0)

但是,如果randInt()生成一个32位整数,这不会填充双精度值的所有位,因为double有53个尾数位。您显然可以生成两个随机整数来填充所有尾数位。或者你可以看看Ramdom.nextDouble()实现的源代码。它几乎可以肯定使用整数 RNG,并简单地将输出转换为双精度值。

至于性能,性能最好的随机数生成器是线性同余生成器。其中,我建议使用数值配方生成器。您可以从维基百科查看有关LCG的更多信息:http://en.wikipedia.org/wiki/Linear_congruential_generator

但是,如果你想要良好的随机性和性能不是那么重要,我认为Mersenne Twister是最好的选择。它还有一个维基百科页面:http://en.wikipedia.org/wiki/Mersenne_Twister

最近有一个名为PCG的随机数生成器,在 http://www.pcg-random.org/ 中进行了解释。这本质上是LCG的一个后处理步骤,可提高LCG输出的随机性。请注意,PCG 比 LCG 慢,因为它只是 LCG 的一个后处理步骤。因此,如果性能非常重要,随机性质量不那么重要,则需要使用LCG而不是PCG。

请注意,我提到的所有生成器都不是加密安全的。如果需要将这些值用于加密应用程序,则应使用加密安全算法。但是,我真的不相信双精度会用于密码学。


推荐