稍后在代码中重置变量会使较早的代码块运行得更慢。为什么?

时间:2014-04-23 21:43:20

标签: java

我有以下程序。当我注意到一些不寻常的东西时,我只是在搞乱其他东西。线" y = 3;"似乎对前一代码块的运行速度有影响。当该行被注释掉时,代码的前半部分比后半部分慢大约十倍。但是,当线路被取消注释时,两个半部分以相同的速度运行。有趣的是,有问题的行不应该做任何事情,因为在那时y的值已经是3。

编辑: 我添加了行" System.out.println(y)"在正上方" y = 3"它打印3.这就是为什么我认为它3.我根据程序的输出进行测量。它打印的两行是两个运行时,底部的Timer代码清楚地显示了我如何测量时间。

/**
 * @author lpreams
 */
public class Misc {
    public static void main(String[] args) {
        new Misc().run();
    }

    public void run() {
        Timer t = new Timer();
        t.start();
        int y = Integer.MIN_VALUE;
        for (int j = 0; j < Integer.MAX_VALUE; ++j) {
            for (int i = 0; i < Integer.MAX_VALUE; ++i) {
                ++y;
            }
        }
        t.stop();
        System.out.println(t.getElapsedTime());
        t.reset();      
        //y = 3;
        t.start();
        for (int j = 0; j < Integer.MAX_VALUE; ++j) {
            for (int i = 0; i < Integer.MAX_VALUE; ++i) {
                ++y;
            }
        }
        t.stop();
        System.out.println(t.getElapsedTime());
    }

    private static class Timer {

        private long startTime = 0;
        private long stopTime = 0;
        private long elapsed = 0;

        public void start() {
            this.startTime = System.nanoTime()/1000000;
        }

        public void stop() {
            this.stopTime = System.nanoTime()/1000000;
            elapsed += stopTime - startTime;
        }

        public long getElapsedTime() {
            return elapsed;
        }
        public void reset() {
            elapsed = 0;
        }
    }
}

我在OS X 10.9.2上的Eclipse中运行此代码。我正在运行最新版本的java。我的机器是MacBook Pro,配备2.4ghz Core 2 Duo和8GB内存。

2 个答案:

答案 0 :(得分:0)

这可能是JIT优化。如果使用以下vm参数运行:

-Djava.compiler = NONE

基于此stackoverflow文章:

how to make sure no jvm and compiler optimization occurs

您可以阻止此操作,并且应该看到相同的结果。我使用这个参数跑了几乎相同的处理时间。

答案 1 :(得分:0)

您从此微基准测试中获得的任何结果都是可疑的。您没有考虑JVM预热效果。

话虽如此,如果我们可以假设效果是 real ,我会把它归结为JIT优化器无法检测到第一个循环体可以被优化掉...当y = 3任务就在那里。你遇到的情况是增加更多的复杂性&#34;阻止优化。它发生了。

(分配的值是无关紧要的。这与JIT编译器的代码生成有关...在之前发生的你预测的y值{{ 1}}可以通过任何东西计算。它可以影响JIT编译器的行为。)