0

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

我的输出是:

Time1: 511 Time2: 228 for N: 100000000
Time1: 509 Time2: 229 for N: 100000001
Time1: 503 Time2: 229 for N: 100000002

我有:

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

我的代码如下所示:

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);
        }

    }
}
4

4 回答 4

9

在 Java 中对代码进行基准测试是很困难的

JVM在后台做了很多事情:

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

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

因此,底线是:如果不深入研究 JVM 和您的操作系统的工作原理,就忘记进行精确的基准测试。你不能期望得到有意义的结果。

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

于 2012-10-16T06:58:44.613 回答
1

您是否多次重复此代码?你得到的时代媒介是什么?时间可能因多种原因而有所不同:例如,您的进程和线程共享相同的 CPU(1 个或更多)和计算机的其他资源。每次你都会得到不同的值,并且差异并不重要。

于 2012-10-16T06:58:47.157 回答
0

请记住:在现代操作系统上运行应用程序有一个副作用:其他应用程序也在其中运行。操作系统调度不同的应用程序并在 CPU 上分配每个进程的时隙。每次执行应用程序时,它都会以不同的顺序与不同的其他进程一起执行。这会影响总执行时间。

于 2012-10-16T07:00:02.283 回答
0

您的系统可用性不受 Java 控制。

如果您注意到,您的所有结果都在同一范围内。这是你可以期待的最好的。

如果即使在 JVM 中也发生了其他一些事情,例如Garbage Collection,您的时间可能会有所不同。

于 2012-10-16T06:59:00.347 回答