2016-09-15 4 views
4

다른 데이터 구조에서 일부 벤치 마크를 실행 중이었고 최종 변수를 선언했을 때 성능이 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

최고 평점은 항상 평균을 의미하지 않습니다 * 올바른 * 때로는 대부분의 사람들이 잘못되었음을 의미합니다. 결과가 항상 재현 가능하지는 않으며 '최종'가 항상 측정 가능한 이익을 부여하지는 않는 것처럼 말입니다. –

답변

4

절대 바꿀 수없는 사항이 있다면 반복해서 찾아 보는 대신 실제 가치의 인라인과 같은 모든 종류의 최적화를 수행 할 수 있습니다. 이것은 설명하기 쉽고 가장 큰 이점을 제공 할 수있는 한 가지 일뿐입니다.

영향이 훨씬 적은 다른 많은 더 복잡한 기술이 있습니다.

당신이 바이트 코드를 보면 당신은이를 볼 특히 전체 클래스 final 비슷한 혜택을 가질 수 있습니다 만들기.

에서 JIT 차기 이후됩니다. 말했다

, 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

관련 문제