Сброс переменной позже в коде замедляет работу более раннего блока кода. Почему?

1

У меня есть следующая программа. Когда я заметил что-то необычное, я просто возился с другими вещами. Линия "y = 3;" похоже, влияет на скорость работы предыдущего блока кода. Когда строка прокомментирована, первая половина кода работает примерно в десять раз медленнее второй половины. Однако, когда линия раскоментирована, обе половины работают с одинаковой скоростью. Интересно, что рассматриваемая линия не должна ничего делать, так как в этом случае значение y уже равно 3.

EDIT: Я добавил строку "System.out.println(y)" прямо над "y = 3", и она печатает 3. Вот почему я думаю, что она 3. И я измеряю на основе вывода программы. Две строки, которые он печатает, - это два времени выполнения, а код таймера внизу показывает, как я измеряю время.

/**
 * @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;
        }
    }
}

Я запускаю этот код в Eclipse на OS X 10.9.2. Я использую последнюю версию java. Моя машина MacBook Pro с 2,4 ГГц Core 2 Duo с 8 ГБ оперативной памяти.

  • 0
    Я не наблюдаю это - даже с профилировщиком. Вы используете Java 8, правильно? (Обратите внимание, что мое профилирование сделано в Java 7.)
  • 0
    Как у тебя уже 3 на тот момент? Это -2147483647
Показать ещё 3 комментария
Теги:

2 ответа

0
Лучший ответ

Любые результаты, полученные вами из этого микро-теста, являются подозрительными. Вы не учитываете эффекты разминки JVM.

Сказав это, если мы можем предположить, что эффект реальный, я бы поставил его на оптимизатор JIT, неспособный обнаружить, что первый корпус цикла можно оптимизировать... когда назначается y = 3. Вы сталкиваетесь с ситуацией, когда добавление немного более "сложной" препятствует оптимизации. Бывает.

(Назначаемое значение несущественно. Все это связано с генерированием кода компилятором JIT... которое происходит до того, как значение y которое вы прогнозируете, будет 3 может быть вычислен любым, что может повлиять на поведение компилятора JIT.)

0

Это потенциально оптимизация JIT. Если вы используете следующий аргумент vm:

нет -Djava.compiler = NONE

на основе этой статьи stackoverflow:

как убедиться в отсутствии оптимизации jvm и компилятора

Вы можете предотвратить это и увидеть тот же результат. Я побежал с этим аргументом и получил почти то же самое время обработки.

  • 0
    Вы знаете, что вам не следовало этого делать. Если вы хотите оставить комментарий, заработайте себе репутацию
  • 0
    И как мне это сделать? принимая участие. Я заинтересовался вопросом и хотел помочь и продолжить обсуждение.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню