java - Math.random() 运行时间与简单算术运算相比如何?

标签 java performance random

在 Java 中,相对于简单的算术运算,Math.random() 生成一个数字需要多长时间?我正在尝试随机分布 ArrayList 中的对象,该对象已经包含值,以便创建稍微均匀但不完全均匀的分布,并且我不确定是否使用 Math.random() 为每个插入点选择随机索引采取的最佳方法。

澄清:插入对象的分布应该足够均匀,使得值不会全部集中在一个区域,但也足够不均匀,使得分布不可预测(如果有人去一个接一个地检查这些值,他们将无法通过检测恒定模式来确定下一个值是否是新插入的值)。

最佳答案

不要使用 Math.random。它依赖于 java.util.Random 的全局实例。使用 AtomicLong在引擎盖下。虽然java.util.Random中使用的PRNG算法是 pretty simple ,性能主要受原子CAS和相关缓存一致性流量的影响。

这对于多线程应用程序来说尤其糟糕(例如 this example ),但即使在单线程情况下也会受到惩罚。

<强> ThreadLocalRandom总是比 Math.random 更可取。它不依赖原子操作,也不会出现争用。它只更新 thread-local state并使用几个 arithmetic and bitwise operations .

这是一个 JMH 基准测试,用于比较 Math.random() 的性能和ThreadLocalRandom.current().nextDouble()到简单的算术运算。

package bench;

import org.openjdk.jmh.annotations.*;
import java.util.concurrent.ThreadLocalRandom;

@State(Scope.Thread)
public class RandomBench {
    double x = 1;

    @Benchmark
    public double multiply() {
        return x * Math.PI;
    }

    @Benchmark
    public double mathRandom() {
        return Math.random();
    }

    @Benchmark
    public double threadLocalRandom() {
        return ThreadLocalRandom.current().nextDouble();
    }
}

结果表明,ThreadLocalRandom 只需几纳秒即可完成工作,其性能可与简单的算术运算相媲美,并且与 Math.random 不同,它可以在多线程环境中完美扩展。

Benchmark                      Threads     Score     Error  Units
RandomBench.mathRandom            1       34.265 ±   1.709  ns/op
RandomBench.multiply              1        4.531 ±   0.108  ns/op
RandomBench.threadLocalRandom     1        8.322 ±   0.047  ns/op

RandomBench.mathRandom            2      366.589 ±  63.899  ns/op
RandomBench.multiply              2        4.627 ±   0.118  ns/op
RandomBench.threadLocalRandom     2        8.342 ±   0.079  ns/op

RandomBench.mathRandom            4     1328.472 ± 177.216  ns/op
RandomBench.multiply              4        4.592 ±   0.091  ns/op
RandomBench.threadLocalRandom     4        8.474 ±   0.157  ns/op

关于java - Math.random() 运行时间与简单算术运算相比如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38546517/

相关文章:

c++ - 生成具有差异约束的随机整数

java - 从对象数组访问对象类型方法 java

java - 写入一个已经存在的文件

java - 正则表达式中的奇怪行为

javascript - 事件事件上的 HTML 元素

python - 将索引列表转换为 2D numpy 数组的最快方法

javascript - 将随机数插入到类中

java - 如何在storm-project中配置不同的logback.xml?

javascript - 结合javascript与图像 Sprite

java - 选择一个随机项目但投票分数存在偏差?