2011-03-24 3 views
1

나는 현재 if 문이 매우 긴이 :switch 문을 if 문으로 사용하거나 case를 hashMap에 넣고 contains 메서드를 사용하는 것이 더 빠릅니까?

if (somesTring != null && !"".equals(somestring) 
    SomeClass.doSomething(); 
else if (somesTring != null && !"".equals(somestring) 
    SomeClass.doAnother(); 
... 
else 
    SomeClass.giveUp(); 

나는 문제의 항목이 결정 트리의 맨 아래에있을 때이 제대로 실행 것이라고 생각합니다. 제 동료의 말에 따르면 switch 문은 더 빠릅니다. 슬픈 일은 switch 문에서 지원하지 않는 문자열로 비교를 수행한다는 것입니다. 어쩌면 나는 관련된 문자열의 해시 코드를 가져 와서 switch 문에 사용할 수있다.

또한 각 문자열을 포함하고 containsKey 메소드의 도움을 받아 결정을 내리는 해시 맵을 고려 중입니다. 그러나 이것은 많은 정적 메서드를 포함하는 클래스를 슬라이스하여 각각의 메서드를 다소 실행 가능한 개체로 만드는 작업과 관련이 있습니다. 이렇게하면 매우 큰 "if"문을 처리 할 수 ​​있습니다.

위의 접근법 중 실행 시간, 우수 실행 및 유지 관리 측면에서 더 효과적인 방법은 무엇입니까? 다른 제안은 환영합니다 :)

+0

문자열의 출처는 어디입니까? Enum을 대신 사용할 수 있습니까? – Rob

+2

이것은 조숙 한 최적화의 냄새가 난다. 이 if 문 세트의 크기는 얼마나되며 얼마나 자주 실행됩니까? –

+1

해시 코드가 작동하지 않을 수 있습니다. 가능성은 낮지 만 동일한 값으로 해시하는 두 개의 문자열을 가질 수도 있습니다. – tvanfosson

답변

4

사용 당신이 경우 문을 제거 할 수 있습니다. 명령 패턴이 완전히 여기

유사하다 더 나은 성능을 제공해야한다 질문

명령을 사용하여 Long list of if statements in Java

,

실행 시간 -.. 당신은 확인할 수는 큰 차이가 될 것 생각하지

우수 사례 - 예

유지 관리 가능성 - 예, 설정된 패턴이 있습니다.

4

"if-else 대신 스위치를 사용하면 더 읽기 쉽고 성능이 좋습니다." 이 코드가 내가 가장 좋아하는 코드 리뷰 주석 중 하나라는 것을 인정해야한다. 좋은 하루 전까지는 Apache Sanselan의 이미지 형식 디코딩 기능을 해킹하면서 동일한 주석을 기반으로 코드를 최적화하려고 시도했지만 벤치 마크에서는 거의 차이가 없었습니다. 나는 그것을 더 조사하는 것에 대해 생각했다. 비록 내 흥미있는 메일 체인을 발견했지만, 내 발견을 게시하는 것에 관한.

먼저 switch 및 if-else 구문에서 일부 샘플을 실행하고 더 자세히 분석하기로 결정했습니다.

세 가지 기능을 쓴 1. 들어 IF-다른 - IF-다른 비교 INT 스위치 (2)에 기초하여 래더 - 20 건으로 스위치, 1 내지 20 3 스위치로 - 희소 랜덤 값 스위치

VM 사양 전환이 문을 두 가지 기능을 한 선택하는 이유는

기능 코드 볼 수 있습니다 "스위치 문 컴파일은 tableswitch 및 lookupswitch 명령어를 사용"하는 경우 - 다른 V iew의 sourceprint

public static void testIfElse(int jumpLabel) { 

    if(1 == jumpLabel) { 
     System.out.println("1"); 
    } else if(2 == jumpLabel) { 
     System.out.println("2"); 
    } else if(3 == jumpLabel) { 
     System.out.println("3"); 
    } else if(4 == jumpLabel) { 
     System.out.println("4"); 
    } 
    // Removed for simplicity 
    else { 
     System.out.println("default"); 
    } 
} 

스위치 기능

유한 스위치 버전 sourceprint보기를 볼 수?

public static void testSwitchFinite(int jumpLable) { 

    switch (jumpLable) { 
     case 1:   
      System.out.println("1"); 
      break; 

     case 2:  
      System.out.println("2"); 
      break; 

     case 3:  
      System.out.println("3");  
      break; 

     case 4:  
      System.out.println("4");  
      break; 

     case 5: 
      System.out.println("5");  
      break; 

     // Removed other cases for simplicity 
     default: 
      System.out.println("default");  
     break; 
    } 
} 

스파 스 스위치 버전 보기 sourceprint?

public static void testSwitchSparse(int jumpLable) { 

    switch (jumpLable) { 
     case 100: 
      System.out.println("1"); 
      break; 

     case -1: 
      System.out.println("2"); 
      break; 

     case 5000: 
      System.out.println("3"); 
      break; 

     case -8: 
      System.out.println("4"); 
      break; 

     case 1600: 
      System.out.println("5"); 
      break; 

     case 250: 
      System.out.println("250"); 
      break; 

     // Removed other cases for simplicity 
     default: 
      System.out.println("default"); 
      break; 
    } 
} 

벤치마킹 시간을 기준으로합니다. 벤치마킹 전략은 간단했습니다. 루프에서이 기능을 실행하고 기능

보기 sourceprint 중 하나 살펴 봅시다 100에서 1000까지

에 이르기까지 반복하여, 그 결과를 볼 수?

public static void testSwitchPerf(int iteration) { 

    long t1 = System.nanoTime(); 
    for (int i = 0; i < iteration; i++) { 
     testSwitchFinite(i); 
    } 

    long t2 = System.nanoTime(); 

    System.out.println("Time Taken (switch) = "+(t2 - t1)/1000000); 

} 

음이 접지 작업, 조건을 실행 한 후, 여기에 데이터

Iteration -> 100 1000 
if-else 8 ms 69 ms 
switch finite 3 ms 34 ms 
switch sparse 7 ms 21 ms 

참고가되었습니다 :이 방법에 데이터가 제공 인해 약간의 차이는 샘플 공간은하지 않습니다 정확한 결과를 제공하십시오. 그러나 샘플 공간이 둘 다 동일하기 때문에 목적에 부합합니다.

결론 1. if-else와 switch 사이에 중요한 실행 차이가 없습니다. 관찰 된 차이는 선택한 샘플 공간 때문입니다. 2. 경우 - 다른, 그 항상 넣어 권장 사용하는 경우 3. 유한 스위치 문 tableswitch 및 스파 스 스위치로 변환 된 경우 - 다른 사다리의 맨 위에있는 조건이 lookupswitch로 변환 된 경우 자주 사용하는

것 이것과 관련하여 그들의 경험에 대해 사람들로부터 듣고 싶습니다. 나는 여전히 가독성을 위해 스위치를 선호한다고 말할 것이다. 이제부터 내 검토 주석을 사용하는 대신, 경우 - 다른 사람의 더 읽기의 전환 "으로 수정

+2

http://wikis.sun.com/display/HotSpotInternals/MicroBenchmarks 및 http://www.ibm.com/developerworks/java/library/j-jtp02225.html을 읽으십시오. ca = drs-j0805 – BalusC

+0

이 통찰력있는 답변에 감사드립니다. 속도 향상이 중요하지 않다는 것을 동료에게 증명할 수 있습니다.) – avendael

+0

이것이 도움이됩니까? 그렇다면 투표하십시오 – developer

관련 문제