2016-09-15 6 views
4

Итак, я выполнял некоторые тесты на разных структурах данных и заметил, что когда я объявлял свои переменные final, я получил 10-20% производительности.Итоговая производительность/оптимизация Java

Это действительно удивило меня. Я думал, что последнее ключевое слово чисто используется для ограничения изменений в переменных, и оптимизация будет определять, является ли какая-либо переменная постоянной или нет.

Вот пример:

import javafx.scene.input.KeyCode; 
import java.util.*; 

public class Main { 
    static /*final*/ int LOOPS = Integer.MAX_VALUE/100; 

    static /*final*/ KeyCode[] keyCodes = KeyCode.values(); 

    public static void main(String[] args) { 
     long startTime; 
     long endTime; 

     testEnumSet(); //warmup 
     startTime = System.nanoTime(); 
     testEnumSet(); 
     endTime = System.nanoTime(); 
     System.out.println(" EnumSet: " + (endTime - startTime) + "ns"); 
    } 

    static /*final*/ EnumSet<KeyCode> enumSet = EnumSet.noneOf(KeyCode.class); 
    static void testEnumSet() { 
     for (int i = 0; i < LOOPS; i++) { 
      /*final*/ KeyCode add = getRandomKeyCode(); 
      if(!enumSet.contains(add)) enumSet.add(add); 

      /*final*/ KeyCode remove = getRandomKeyCode(); 
      if(enumSet.contains(remove)) enumSet.remove(remove); 
     } 
    } 

    /*final*/ static Random random = new Random(); 
    static KeyCode getRandomKeyCode() { 
     return keyCodes[random.nextInt(keyCodes.length)]; 
    } 
} 

С окончательным: .... EnumSet: 652 266 207ns
Без финале: EnumSet: 802 121 596ns

Это последовательно воспроизводимые!

Почему существует такая огромная разница между кодом, который использует final, и кодом, который этого не делает? Почему он не оптимизирован? И почему в любом случае окончательно быстрее, какова разница в сгенерированном байт-коде?

+0

[Дублированный] (http://stackoverflow.com/questions/4279420/does-use-of-final-keyword-in-java-improve-the-performance?rq=1) –

+1

@ JarrodRoberson - лучший рейтинг ответов, который не показывает прирост производительности, но мои тесты показывают прирост производительности на 20%, поэтому я не думаю, что это дубликат. – Jhonny007

+0

рейтинг не означает всегда означает * правильно * иногда это просто означает, что большинство людей ошибаются. Точно так же, как ваши результаты не всегда будут воспроизводимыми, а 'final' не всегда будет давать какие-либо измеримые выигрыши. –

ответ

4

Если что-то никогда не может измениться, вы можете делать всевозможные оптимизации, например, встраивание фактического значения, а не поиск его снова и снова. Это всего лишь одно, что вы можете сделать, что легко объяснить и приносит наибольшую пользу.

Есть много других более эзотерических вещей, которые имеют гораздо меньшее влияние.

Если вы посмотрите на байткод вы увидите это, особенно после того, как JIT пинков в.

Заставить весь класс final может иметь те же преимущества.

Это говорит, final ссылка не всегда будет обеспечивать измеримые выгод, это зависит от использования ссылки. В этом случае EnumSet делает много особого соуса под капотом, если вы посмотрите у источника. Неизменяемые ссылки, вероятно, встраиваются как часть , что.

Также обратите внимание, что поведение, которое вы видите, может исчезнуть в будущей версии JVM или не будет присутствовать в других реализациях JVM. Все, что может быть изменено из-под вас, не зависит от какой-либо конкретной реализации.

Here is some more information in greater detail about all the idiomatic uses of final.

+0

Да, но я думал, что JVM достаточно умен, чтобы обнаружить, что переменная является окончательно окончательной, если она никогда не изменяется (особенно в такой простой части кода) и может ее оптимизировать. – Jhonny007

+0

Нет, он не может предсказать будущее, все, что явно не ограничено изменениями, может измениться в любое время в будущем, только потому, что оно не изменилось в последних 100K исполнениях, это не значит, что он не будет для 100 001st. –

+0

Но разве это не то, что можно было бы выяснить во время компиляции, если поле изменилось? Я имею в виду, что если вы попытаетесь изменить конечное поле, компилятор замечает и останавливает вас. – Jhonny007

 Смежные вопросы

  • Нет связанных вопросов^_^