gpt4 book ai didi

java - 当每个 "draw"仅使用一位时(例如调用 nextBoolean),为什么伪随机位不被缓存?

转载 作者:行者123 更新时间:2023-12-01 13:32:28 25 4
gpt4 key购买 nike

我正在浏览source code for Math.Random我注意到 nextBoolean() 的源代码

public boolean nextBoolean() {
return next(1) != 0;
}

通过 next(int bits) 调用新的伪随机位绘制它将 LC-PRNG“迭代”到下一个状态,即“绘制”一整套新位,即使 nextBoolean 中只使用了一个位。这实际上意味着其余的位(确切地说是 47 位)在该特定迭代中几乎被浪费了。

我看过另一个 PRNG,它看起来基本上做同样的事情,尽管底层生成器不同。由于同一迭代中的多个位用于其他方法调用(例如 nextInt()nextLong()...),并且连续位被假定为彼此“足够独立”。

所以我的问题是:为什么使用 nextBoolean() 绘制 PRNG 时只使用一位?应该可以缓存,比如 16 位(如果想使用最高质量的位),连续调用 nextBoolean(),我在这里弄错了吗?

编辑:我所说的缓存结果的意思是这样的:

private long booleanBits = 0L;
private int c = Long.SIZE;
public boolean nextBoolean(){
if(c == 0){
booleanBits = nextLong();
c = Long.SIZE;
}

boolean b = (booleanBits & 1) != 0;
booleanBits >>>= 1;
return b;

//return ( next() & 1 ) != 0;
}

当然,它不像注释掉的文本那么确定和漂亮,但最终的绘制次数减少了 64 倍。每次调用 nextBoolean() 需要 1 次 int 比较和 1 次右移操作。我是不是搞错了?

Edit2: 好的,我必须测试时间,请参阅代码 here 。输出结果如下:

Uncached time lapse: 13891
Cached time lapse: 8672

Testing if the order matters..:
Cached time lapse: 6751
Uncached time lapse: 8737

这表明缓存位不是计算负担,而是一种改进。关于此测试我应该注意以下几点:

  1. 我使用 xorshift* 生成器的自定义实现,该实现深受 Sebastiano Vigna's work on xorshift* generators 的启发。 。

  2. xorshift* 生成器实际上比 Java 的 native 生成器快得多。因此,如果我使用 java.util.Random 来绘制我的位,缓存会产生更大的影响。或者说至少这是我所期望的。

  3. 此处假定单线程应用程序,因此没有 sych 问题。但这当然在这两种情况下都很常见。

最佳答案

任何类型的条件都可能非常昂贵(参见 Why is it faster to process a sorted array than an unsorted array? )和 next它本身并没有做那么多的操作:我计算了五个算术运算加上一个compareAndSet,这在单线程上下文中应该不会花费太多。

compareAndSet 指出了另一个问题——线程安全——当您有两个需要保持同步的变量时,线程安全会变得更加困难,例如 booleanBitsc 。保持多线程使用同步的同步开销几乎肯定会超过 next() 的成本。打电话。

关于java - 当每个 "draw"仅使用一位时(例如调用 nextBoolean),为什么伪随机位不被缓存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21484483/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com