반응형
다음과 같이 같은 기능을 하는 switch문과 if문을 작성해보자.
public class SwitchAndIf {
public static void switchTest(int num) {
switch (num) {
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;
default:
System.out.println("알 수 없는 숫자입니다.");
}
}
public static void IfTest(int num) {
if (num == 1) {
System.out.println("숫자 1입니다.");
} else if (num == 2) {
System.out.println("숫자 2입니다.");
} else if (num == 3) {
System.out.println("숫자 3입니다.");
} else if (num == 4) {
System.out.println("숫자 4입니다.");
} else if (num == 5) {
System.out.println("숫자 5입니다.");
} else {
System.out.println("알 수 없는 숫자입니다.");
}
}
}
그리고 두 함수의 바이트코드를 비교해보자. 먼저 if문의 바이트코드를 살펴보자.
public static IfTest(I)V
L0
LINENUMBER 25 L0
ILOAD 0
ICONST_1
IF_ICMPNE L1
L2
LINENUMBER 26 L2
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\uc22b\uc790 1\uc785\ub2c8\ub2e4."
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
GOTO L3
L1
LINENUMBER 27 L1
FRAME SAME
ILOAD 0
ICONST_2
IF_ICMPNE L4
L5
LINENUMBER 28 L5
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\uc22b\uc790 2\uc785\ub2c8\ub2e4."
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
GOTO L3
L4
LINENUMBER 29 L4
FRAME SAME
ILOAD 0
ICONST_3
IF_ICMPNE L6
L7
LINENUMBER 30 L7
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\uc22b\uc790 3\uc785\ub2c8\ub2e4."
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
GOTO L3
L6
LINENUMBER 31 L6
FRAME SAME
ILOAD 0
ICONST_4
IF_ICMPNE L8
L9
LINENUMBER 32 L9
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\uc22b\uc790 4\uc785\ub2c8\ub2e4."
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
GOTO L3
L8
LINENUMBER 33 L8
FRAME SAME
ILOAD 0
ICONST_5
IF_ICMPNE L10
L11
LINENUMBER 34 L11
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\uc22b\uc790 5\uc785\ub2c8\ub2e4."
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
GOTO L3
L10
LINENUMBER 36 L10
FRAME SAME
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\uc54c \uc218 \uc5c6\ub294 \uc22b\uc790\uc785\ub2c8\ub2e4."
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L3
LINENUMBER 38 L3
FRAME SAME
RETURN
L12
LOCALVARIABLE num I L0 L12 0
MAXSTACK = 2
MAXLOCALS = 1
위 코드를 보면 if문을 각각의 조건을 IF_ICMPNE (If Integer Compare Not Equal) 명령어로 값을 비교한다. 때문에 아래 그림처럼 조건이 많아 질수록 연산량이 늘어난다.
이번에는 switch문의 바이트코드를 살펴보자.
public static switchTest(I)V
L0
LINENUMBER 3 L0
ILOAD 0
TABLESWITCH
1: L1
2: L2
3: L3
4: L4
5: L5
default: L6
L1
LINENUMBER 5 L1
FRAME SAME
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\uc22b\uc790 1\uc785\ub2c8\ub2e4."
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L7
LINENUMBER 6 L7
GOTO L8
L2
LINENUMBER 8 L2
FRAME SAME
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\uc22b\uc790 2\uc785\ub2c8\ub2e4."
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L9
LINENUMBER 9 L9
GOTO L8
L3
LINENUMBER 11 L3
FRAME SAME
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\uc22b\uc790 3\uc785\ub2c8\ub2e4."
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L10
LINENUMBER 12 L10
GOTO L8
L4
LINENUMBER 14 L4
FRAME SAME
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\uc22b\uc790 4\uc785\ub2c8\ub2e4."
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L11
LINENUMBER 15 L11
GOTO L8
L5
LINENUMBER 17 L5
FRAME SAME
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\uc22b\uc790 5\uc785\ub2c8\ub2e4."
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L12
LINENUMBER 18 L12
GOTO L8
L6
LINENUMBER 20 L6
FRAME SAME
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\uc54c \uc218 \uc5c6\ub294 \uc22b\uc790\uc785\ub2c8\ub2e4."
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L8
LINENUMBER 22 L8
FRAME SAME
RETURN
L13
LOCALVARIABLE num I L0 L13 0
MAXSTACK = 2
MAXLOCALS = 1
코드의 앞 부분을 보면 TABLESWITCH가 생성된다. 이것은 점프 테이블(분기 테이블)로 특정 조건의 데이터가 입력되면 프로그램의 제어를 프로그램의 다른 부분으로 옮기게된다. 이러한 방식의 차이로 일반적으로 switch문이 if-else 문 보다 빠를 수 있다.
실제론
실제로는 다음과 같은 이유로 이론과 다를 수 있다.
1. 대부분의 경우 처음 if문에서 처리되고, 아주 일부만 else에서 처리되는 경우가 있을 수 있다.
2. CPU의 분기 예측(branch prediction) 알고리즘이 if 쪽에서 더 잘 이루어질 수 있다.
이러한 이유로 if문을 사용할 때는 if문 분기 앞쪽에 더 많이 발생하는 조건을 넣는 것이 더 유리하다.
반응형
'자바' 카테고리의 다른 글
[Java] JDK가 제공하는 기본 개발 도구 (javac, java, javadoc, jps, jmap) (0) | 2021.12.06 |
---|---|
J2EE 디자인 패턴 - Session Facade Pattern (0) | 2021.12.06 |
J2EE 디자인 패턴 - Data Access Object Pattern (0) | 2021.12.05 |
J2EE 디자인 패턴이란? (0) | 2021.12.03 |
J2EE 디자인 패턴 - Business Delegate Pattern (0) | 2021.12.03 |
댓글