В приведенном ниже коде выполняется один и тот же расчет 3 раза (он не делает много: в основном добавляет все числа от 1 до 100 м). Первые 2 блока работают примерно в 10 раз быстрее, чем третий. Я запустил эту тестовую программу более 10 раз, и результаты показывают очень небольшую дисперсию.
Во всяком случае, я ожидаю, что третий блок будет работать быстрее (компиляция JIT), но типичный вывод:
35974537
36368455
296471550
Может кто-нибудь объяснить, что происходит? (Чтобы быть ясным, я не пытаюсь ничего исправить здесь, просто пытаюсь лучше понять, что происходит)
Примечание:
- GC не запускается во время программы (контролируется с помощью
-XX:+PrintGC
) - тестируется с версиями Oracle JDK 1.6.0_30, 1.7.0_02 и 1.7.0_05
- также тестировался со следующими параметрами:
-XX:+PrintGC -Xms1000m -Xmx1000m -XX:NewSize=900m
= > тот же результат - блок вместо этого помещается в цикл, все прогоны
- если блок извлекается в метод, все прогоны выполняются быстро (независимо от того, вызван ли метод 3 раза или в цикле не имеет значения)
public static void main(String... args) {
//three identical blocks
{
long start = System.nanoTime();
CountByOne c = new CountByOne();
int sum = 0;
for (int i = 0; i < 100000000; i++) {
sum += c.getNext();
}
if (sum != c.getSum()) throw new IllegalStateException(); //use sum
long end = System.nanoTime();
System.out.println((end - start));
}
{
long start = System.nanoTime();
CountByOne c = new CountByOne();
int sum = 0;
for (int i = 0; i < 100000000; i++) {
sum += c.getNext();
}
if (sum != c.getSum()) throw new IllegalStateException(); //use sum
long end = System.nanoTime();
System.out.println((end - start));
}
{
long start = System.nanoTime();
CountByOne c = new CountByOne();
int sum = 0;
for (int i = 0; i < 100000000; i++) {
sum += c.getNext();
}
if (sum != c.getSum()) throw new IllegalStateException(); //use sum
long end = System.nanoTime();
System.out.println((end - start));
}
}
public static class CountByOne {
private int i = 0;
private int sum = 0;
public int getSum() {
return sum;
}
public int getNext() {
i += 1;
sum += i;
return i;
}
}