java.util.Random使计算速度提高100倍?

时间:2018-11-03 17:48:22

标签: java benchmarking

我完全不知所措,我不知道发生了什么事...

//import java.util.Random;

public class TestInProgress {
    public static void main(String[] args) {
        long start, end;
        long average;

//      Random random= new Random();

    for(int j=0; j<5; j++) {

        average= 0L;
        for(int i=0; i<100; i++) {

            start= System.nanoTime();
                double temp= fastComputeSigm(0.0);
            end= System.nanoTime();
            average+= (end - start);
        }

        average= average/ 100L;
        System.out.println("AVERAGE FASTCOMPUTE: "+average);

        average= 0L;
        for(int i=0; i<100; i++) {

            start= System.nanoTime();
                double temp= Math.exp(0.0)/(1.0 + Math.exp(0.0));
            end= System.nanoTime();

            average+= (end - start);
        }

        average= average / 100L;
        System.out.println("AVERAGE SIGMOID: "+average);
    }
}

static double fastComputeSigm(double value) {
    return 0.0;
}

}

最令人惊讶的是输出:

  

最快的计算机:98 平均SIGMOID: 38625 :最快的计算机:   106平均SIGMOID:65平均快速计算机:299平均SIGMOID:201   平均快速计算机:36平均速度:65平均快速计算机:53   平均SIGMOID:57

看到了吗?我未评论随机(及其导入) 您会期待什么?输出:

  

最快的计算机:90 平均SIGMOID:324 最快的计算机:131   平均SIGMOID:73平均快速计算机:217平均SIGMOID:36   平均快速计算机:53平均速度:12平均快速计算机:53   平均SIGMOID:69

我在日食Oxygen.3a版本(4.7.3a)上尝试了此操作 我正在使用Java 10.0.2 我的电脑装有Intel Core i5-7300HQ 具有这些高速缓存的存储器:L1 256,L2 1024,L3 6M 我在Windows 10上运行

注意:我试图用j <1,2,3,...来使forloop多次,第一个Sigmoid 总是有荒谬的时间长度

编辑:尝试使用Windows命令行(javac和java)启动它,结果相同

1 个答案:

答案 0 :(得分:1)

通常,指向您指出微基准测试的技巧的评论是正确的,您应该使用JMH。在这种特殊情况下,您的计时/基准测试代码似乎引入了延迟,而延迟根本没有。

这是您代码的压缩版本,它表明问题不是由使用Random而是由System.nanoTime()(内部Random()调用)触发的。

public static void main(String[] args) {
    long start, end, average;
    double temp = 0;

    // start = System.nanoTime();

    average = 0L;
    for (int i = 0; i < 100; i++) {
        start = System.nanoTime();
        temp += Math.exp(0.0) / (1.0 + Math.exp(0.0));
        end = System.nanoTime();

        average += (end - start);
        // System.out.println(i + " " + (end - start));
    }
    System.out.println("AVERAGE: " + (average / 100));
    System.out.println("temp: " + temp);
}

当我取消评论start = System.nanoTime()时,我会观察到x100加速-在这一点上,重要的是要记住这里的单位是nanoseconds,所以我们非常对它的任何内容都非常敏感是运行时在后台执行的。如果您取消对System.out.println(i + " " + (end - start));的评论,您会偶尔看到打ic ,这是整个速度下降的原因。尽管追逐的原因可能很有趣,但以下版本的代码表明这是由于测量而不是核心功能引起的,因此您可能需要确保这是您需要的想在[1]上花费自己的时间:

public static void main(String[] args) {
    double temp = 0;

    long start = System.nanoTime();

    for (int i = 0; i < 100; i++) {
        temp += Math.exp(0.0) / (1.0 + Math.exp(0.0));
    }

    System.out.println("AVERAGE: " + ((System.nanoTime() - start) / 100));
    System.out.println("temp: " + temp);
} 

此处的AVERAGE值与以前的版本相似,未注释start = System.nanoTime()

[1]如果您想更深入地研究这种特定行为,请尝试在运行-Xint VM选项(禁用编译器)的同时计时测试时间。