У меня есть следующая программа. Когда я заметил что-то необычное, я просто возился с другими вещами. Линия "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 ГБ оперативной памяти.
Любые результаты, полученные вами из этого микро-теста, являются подозрительными. Вы не учитываете эффекты разминки JVM.
Сказав это, если мы можем предположить, что эффект реальный, я бы поставил его на оптимизатор JIT, неспособный обнаружить, что первый корпус цикла можно оптимизировать... когда назначается y = 3
. Вы сталкиваетесь с ситуацией, когда добавление немного более "сложной" препятствует оптимизации. Бывает.
(Назначаемое значение несущественно. Все это связано с генерированием кода компилятором JIT... которое происходит до того, как значение y
которое вы прогнозируете, будет 3
может быть вычислен любым, что может повлиять на поведение компилятора JIT.)
Это потенциально оптимизация JIT. Если вы используете следующий аргумент vm:
нет -Djava.compiler = NONE
на основе этой статьи stackoverflow:
как убедиться в отсутствии оптимизации jvm и компилятора
Вы можете предотвратить это и увидеть тот же результат. Я побежал с этим аргументом и получил почти то же самое время обработки.
-2147483647