为什么Java中的时代不同

Daw*_*ozd 0 java

我想知道为什么这段代码会返回不同的时间:

我的输出是:

Time1: 511 Time2: 228 for N: 100000000
Time1: 509 Time2: 229 for N: 100000001
Time1: 503 Time2: 229 for N: 100000002
Run Code Online (Sandbox Code Playgroud)

我有:

java version "1.6.0_24"
OpenJDK Runtime Environment (IcedTea6 1.11.4) (6b24-1.11.4-1ubuntu0.12.04.1)
OpenJDK Server VM (build 20.0-b12, mixed mode)
Intel® Pentium(R) CPU B960 @ 2.20GHz × 2 
Linux Ubuntu 12.04
Run Code Online (Sandbox Code Playgroud)

我的代码看起来像:

public class test {

    public static void main(String[] arg)
    {
        for(long N=100000000;N<2000000000;++N){

            long time2 = System.currentTimeMillis();
            double d = 1.0; 
            double z = 1.0/3.0;
            for(long i = 0; i < N; i++)
            {
                d = d*z;
            }
            long result2 = System.currentTimeMillis() - time2;


            long time1 = System.currentTimeMillis();
            double x = 1.0;
            double f = 1.0/3.0;
            for(long i = 0; i < N; i++)
            {
                x = x*f;
            }
            long result1 = System.currentTimeMillis() - time1;



            System.out.println("Time1: " + result1 + " Time2: " + result2 + " bigger: " + (result1 > result2) + " for N: " + N);
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

Bru*_*eis 9

用Java标记代码很难.

JVM 在后台做了很多事情:

  • 它可以动态优化代码,
  • 在调用它们一定次数之后编译方法(因此方法可以突然变得更快,但编译会消耗资源,所以一切都可能会变慢一段时间),
  • 如果它看起来合适,它可以在变量外部移动变量,
  • 它甚至可以简单地删除一些代码,如果它看到它什么也不做(例如:你正在计算d,但你没有对它做任何事情,那么为什么要计算呢?允许JVM简单地删除那些代码;阅读"逃避分析").
  • 可能还会发生一些垃圾收集等.

此外,您的操作系统可能会干扰JVM的执行等.

因此,最重要的是:如果不仔细研究JVM和操作系统的工作方式,就不要忘记做精确的基准测试.你不能期望获得有意义的结果.

有关更多信息,请查看此问题和答案.它包含非常好的论文链接.