2

switch 문에 입력을 기반으로 다른 구성된 객체를 반환하는 약 40 개의 사례가 들어있는 경우가 있습니다. 이 방법은 메트릭에서 순환 복잡도가 너무 높다고 표시되며 일반적으로이를 핸들러 개체의 맵으로 변경합니다. 그러나이 스위치는 성능이 중요한 코드 조각에 위치하므로 HashMap 조회 및 핸들러 호출이 성능 측면에서 스위치 블록 실행과 비교되는 방법에 대한 질문을 생각해 냈습니다. 아무도 아직 비교하지 않았습니까? 고려 가치가 있니? 또는 유한 키 숫자에 대한 더 빠른 조회 객체가 있습니까? 내 생각 엔 어떤 차이가 무시할 수 있다는 것입니다 수 있도록java switch cyclomatic complexity vs performance

건배, 카이

+1

성능을 측정 해보십시오. –

답변

0

값을 검색하는 것이 스위치 방식보다 약간 빠릅니다. 코드 변경이 종종 해시 접근법에 중점을 두는 경우가 많습니다.이를 수정하고 자주 변경하지 않으면 회상없이 스위치 접근 방식을 사용할 수 있습니다. 여러 프로그래머가 응용 프로그램을 개발중인 경우 해시 방식을 prevent future bugs으로 변경하는 것이 좋습니다.

스위치 버전 : 27.32191395 ns. 해시 버전 : 26.98444367 ns.

해시로 얻은 시간 : 1.23 %.

다음 코드를 사용하여 테스트했습니다.

import java.util.Random;

/** 
* @author ruslan.lopez 
*/ 
public class CyclomaticVsHash { 

    private static final Random RNG = new Random(); 
    static int[]    myHash = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
      12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 
      29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 }; 

    /** 
    * @param args 
    *   the command line arguments 
    */ 
    public static void main(String[] args) { 
     long iterations = 100000000; 
     warmUp(iterations); 
     System.out.println("Cycle1"); 
     double individualTime = getAverageTimePerIterationc1(iterations); 
     iterations = 10000; 
     double totalTime = getTotalTimec1(iterations); 

     System.out.println("ns/iteration: " + individualTime); 
     System.out.println("Total time for " + iterations + " runs: " 
          + totalTime); 

     System.out.println("Cycle2"); 
     iterations = 100000000; 
     warmUp(iterations); 
     double individualTime1 = getAverageTimePerIterationc2(iterations); 
     iterations = 10000; 
     double totalTime1 = getTotalTimec2(iterations); 

     System.out.println("ns/iteration: " + individualTime1); 
     System.out.println("Total time for " + iterations + " runs: " 
          + totalTime1); 

    } 

    public static void warmUp(long iterations) { 
     System.out.println("Starting warmup"); 
     for (int i = 0; i < iterations; i++) { 
      runCycles(); 
      runCycles1(); 
     } 
    } 

    public static double getAverageTimePerIterationc1(long iterations) { 
     // test 
     System.out.println("Starting individual time test"); 
     long timeTaken = 0; 
     for (int i = 0; i < iterations; i++) { 
      long startTime = System.nanoTime(); 
      runCycles(); 
      timeTaken += System.nanoTime() - startTime; 
     } 
     return (double) timeTaken/iterations; 
    } 

    public static long getTotalTimec1(long iterations) { 
     // test 
     System.out.println("Starting total time test"); 
     long timeTaken = 0; 
     for (int i = 0; i < iterations; i++) { 
      long startTime = System.nanoTime(); 
      runCycles(); 
      timeTaken += System.nanoTime() - startTime; 
     } 
     return timeTaken; 
    } 

    public static double getAverageTimePerIterationc2(long iterations) { 
     // test 
     System.out.println("Starting individual time test"); 
     long timeTaken = 0; 
     for (int i = 0; i < iterations; i++) { 
      long startTime = System.nanoTime(); 
      runCycles1(); 
      timeTaken += System.nanoTime() - startTime; 
     } 
     return (double) timeTaken/iterations; 
    } 

    public static long getTotalTimec2(long iterations) { 
     // test 
     System.out.println("Starting total time test"); 
     long timeTaken = 0; 
     for (int i = 0; i < iterations; i++) { 
      long startTime = System.nanoTime(); 
      runCycles1(); 
      timeTaken += System.nanoTime() - startTime; 
     } 
     return timeTaken; 
    } 

    private static void runCycles() { 
     Integer num = RNG.nextInt(); 
     int newnum; 
     switch (num) { 
      case 1: 
       newnum = num * 1; 
       break; 
      case 2: 
       newnum = num * 2; 
       break; 
      case 3: 
       newnum = num * 3; 
       break; 
      case 4: 
       newnum = num * 4; 
       break; 
      case 5: 
       newnum = num * 5; 
       break; 
      case 6: 
       newnum = num * 6; 
       break; 
      case 7: 
       newnum = num * 7; 
       break; 
      case 8: 
       newnum = num * 8; 
       break; 
      case 9: 
       newnum = num * 9; 
       break; 
      case 10: 
       newnum = num * 10; 
       break; 
      case 11: 
       newnum = num * 11; 
       break; 
      case 12: 
       newnum = num * 12; 
       break; 
      case 13: 
       newnum = num * 13; 
       break; 
      case 14: 
       newnum = num * 14; 
       break; 
      case 15: 
       newnum = num * 15; 
       break; 
      case 16: 
       newnum = num * 16; 
       break; 
      case 17: 
       newnum = num * 17; 
       break; 
      case 18: 
       newnum = num * 18; 
       break; 
      case 19: 
       newnum = num * 19; 
       break; 
      case 20: 
       newnum = num * 20; 
       break; 
      case 21: 
       newnum = num * 21; 
       break; 
      case 22: 
       newnum = num * 22; 
       break; 
      case 23: 
       newnum = num * 23; 
       break; 
      case 24: 
       newnum = num * 24; 
       break; 
      case 25: 
       newnum = num * 25; 
       break; 
      case 26: 
       newnum = num * 26; 
       break; 
      case 27: 
       newnum = num * 7; 
       break; 
      case 28: 
       newnum = num * 28; 
       break; 
      case 29: 
       newnum = num * 29; 
       break; 
      case 30: 
       newnum = num * 30; 
       break; 
      case 31: 
       newnum = num * 31; 
       break; 
      case 32: 
       newnum = num * 32; 
       break; 
      case 33: 
       newnum = num * 33; 
       break; 
      case 34: 
       newnum = num * 34; 
       break; 
      case 35: 
       newnum = num * 35; 
       break; 
      case 36: 
       newnum = num * 36; 
       break; 
      case 37: 
       newnum = num * 37; 
       break; 
      case 38: 
       newnum = num * 38; 
       break; 
      case 39: 
       newnum = num * 39; 
       break; 
      default: 
       newnum = num * 40; 
       break; 
     } 
    } 

    private static void runCycles1() { 
     Integer num = RNG.nextInt(); 
     int nwenum = num > 0 && num < 39 
             ? myHash[num - 1] 
             : myHash[39]; 
    } 
} 
3

는 I는 switch의 내부 표현이 HashMap 유사한 구조를 가질 것 룩업 테이블의 어떤 종류를 사용하는 확신 해요.

여기서는 성능을 고려해 볼 가치가 없다고 말하지만 가장 깨끗한 코드를 제공하는 솔루션을 선택하십시오.