2014-10-23 5 views
3

Java 컴파일러 또는 런타임 (또는 다른 언어 컴파일러)이 브랜치 3을 실현할 수있을만큼 똑똑하고 스마트하게 구현할 수 있습니까? 나는 많은 초기 개발자들과 함께 이런 종류의 "방어 프로그래밍"을 보았으며,이 죽은 무게가 바이트 코드에 머무르는 지 궁금해합니다. 자바 컴파일러가이 코드를 최적화 할 수 있습니까?

import java.util.Random; 


class Example 
{ 
    public static void main(String[] args) { 
     int x = new Random().nextInt() % 10; 
     if (x < 5) 
     { 
      System.out.println("Case 1"); 
     } 
     else 
      if (x >= 5) 
      { 
       System.out.println("Case 2"); 
      } 
      else 
      { 
       System.out.println("Case 3"); 
      } 

    } 
} 

또는이 더 무딘 경우

boolean bool = new Random().nextBoolean(); 
if (bool) 
{ 
    System.out.println("Case 1"); 
} 
else 
    if (bool) 
    { 
     System.out.println("Case 2"); 
    } 
+1

JITC가 알아낼 수 있습니다. 아니면 매우 드문 것으로 프로파일 링을 통해 테스트를 최적화하고 실제 코드를 라인 밖으로 이동시킬 수 있습니다. (javac이 그것을 최적화하는 것은 아주 드문 일입니다.) –

+3

측점 :'nextInt() % n' 대신'nextInt (n)'을 호출하십시오. 그것은 다양한 까다로운 경우를 처리합니다. http://docs.oracle.com/javase/7/docs/api/java/util/Random.html#nextInt(int) – Jerry101

답변

4

내가하지 않는 것이 자바 8 컴파일러는 그것을 멀리 최적화 할 수 있습니다. 컴파일 한 후 바이트 코드를 검사하는 "은 javap -c"사용 :

public static void main(java.lang.String[]); 
    Code: 
     0: new   #2     // class java/util/Random 
     3: dup 
     4: invokespecial #3     // Method java/util/Random."<init>":()V 
     7: invokevirtual #4     // Method java/util/Random.nextInt:()I 
     10: bipush  10 
     12: irem 
     13: istore_1 
     14: iload_1 
     15: iconst_5 
     16: if_icmpge  30 
     19: getstatic  #5     // Field java/lang/System.out:Ljava/io/PrintStream; 
     22: ldc   #6     // String Case 1 
     24: invokevirtual #7     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
     27: goto   54 
     30: iload_1 
     31: iconst_5 
     32: if_icmplt  46 
     35: getstatic  #5     // Field java/lang/System.out:Ljava/io/PrintStream; 
     38: ldc   #8     // String Case 2 
     40: invokevirtual #7     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
     43: goto   54 
     46: getstatic  #5     // Field java/lang/System.out:Ljava/io/PrintStream; 
     49: ldc   #9     // String Case 3 
     51: invokevirtual #7     // Method java/io/PrintStream.println:(Ljava/lang/String;)V 
     54: return 
} 

문자열 "사례 3은"여전히 바이트 코드에 존재합니다.

+0

감사합니다. 문제가 생겨서 저장되었습니다. –

+0

Javac은 결코 그런 것들을 최적화하지 않습니다. 그것은 JIT 컴파일러 작업입니다. – leventov

+0

@leventov JIT는 죽은 코드를 제거하지 않을 것입니다, 그냥 거기에 앉아 있습니다. 그것은 또한 그곳에 앉아있는 것 외에는 아무 것도하지 않는 것이라고 말했다. 제거 할 수있는 중요한 시간 최적화는 없습니다 (감지 될 수있는 경우). –