출처 : 온라인 게임 개발자 이창연(lisyoen) http://blog.empas.com/lisyoen/
switch 는 C/C++, Java, C#, J++, J# 등에서 널리 쓰이는 조건 분기문이다.
다른 언어에서도 비슷한 기능의 조건 분기문이 존재한다.
C/C++ 에서는 그 제약이 크다. switch 구문에서는 반드시 정수(int)만 비교할 수 있고 분기하는 case 에는 상수(constant value)만 넣을 수 있다. (다른 고급언어들은 부동소수점, 문자열 심지어는 사용자 정의 데이터 타입 까지 비교할 수 있다) 이 제약은 고속 스위칭(switching)을 위해 존재하는 것이다.
과연 C/C++ 의 switch 구문은 어떤 방식으로 작동할까?
흔히 알려진 바로는 switch 구문이 if/else 비교 없이 해당 case 로 곧장 jump 하기 때문에 속도가 빠르다고 한다. 이것은 부분적으로 사실이다. 컴파일러가 이런 방식을 사용하게 된 것은 DOS 시절의 WATCOM C 부터였다고 한다.
프로그래머라면 생각해보자. 비교할 값만으로 jump 하려면 Address table 이 필요하다. 과연 Address table 만으로 switch 구문을 비교 없이 jump 하도록 구성할 수 있을까? 오래 생각하지 말자. 당연히 불가능하다.
32bit 플랫폼에서 int 는 4Giga 의 범위를 갖는다. Address point 도 4bytes 일 경우 Address table 은 최대 16GB 의 메모리를 사용할 수도 있다. (case 0, case 0xFFFFFFFF)
이에 대한 해답은. 바로 '조합' 이다.
즉, 연속적이거나 집적된 case 의 경우에는 해당 범위만큼의 테이블을 만들어 jump 하고 듬성듬성 떨어져 있는 case 의 경우는 if/else 를 이용하여 case 수 만큼 비교후 분기하는 것이다.
VC++ 6.0 과 7.0 의 디스어셈블리 기능을 이용해 분석해본바에 의하면 switch 구문은 다음과 같은 규칙을 갖고 기계어를 생성한다.
1. case 가 3개 이하인 경우에는 if/else 로 일일히 비교후 분기 한다.
2. case 가 4개 이상이고, 최소 case 와 최대 case 의 차이가 254 이하인 경우에는 Address table 을 만들어 jump 한다. (이 과정에서 최대 약 1KB 의 Address table 이 생성된다. switch 를 잘못 쓰면 1KB 의 디스크 공간과 메모리를 낭비할 수도 있다)
3. 최소 case 와 최대 case 의 차이가 255 이상인 경우에는 if/else 로 비교후 분기한다. 단, 최소 case 를 포함하며 규칙2의 조건을 만족하는 부분집합이 존재할 경우 해당 case 들은 Address table 을 만들어 jump 한다.
예>
case 0, 1, 2 -> if/else 로 분기 (규칙 1)
case 0, 1, 2, 3, 4 -> Address table 로 분기 (규칙2)
case 0, 1, 2, 3, 4, 100 -> Address table 로 분기 (규칙 2)
case 0, 1, 2, 3, 4, 100, 300 -> 0~100 까지는 Address table 로 분기. 300 은 if/else 로 분기(규칙3)
case 0, 300, 301, 302, 303, 304 -> 모두 if/else 로 분기 (규칙3)
이 외에도 몇 가지 규칙이 더 있을것으로 보인다. 하지만 이것 만으로도 벌써 switch 구문을 효과적으로 활용하기 위한 제한사항들이 머리속에 마구 떠오를 것이다. (5번째 예와 같이 구성해서는 안될것이다)
이런 작은 차이로부터 우리는 명품을 끌어낸다
switch 는 C/C++, Java, C#, J++, J# 등에서 널리 쓰이는 조건 분기문이다.
다른 언어에서도 비슷한 기능의 조건 분기문이 존재한다.
C/C++ 에서는 그 제약이 크다. switch 구문에서는 반드시 정수(int)만 비교할 수 있고 분기하는 case 에는 상수(constant value)만 넣을 수 있다. (다른 고급언어들은 부동소수점, 문자열 심지어는 사용자 정의 데이터 타입 까지 비교할 수 있다) 이 제약은 고속 스위칭(switching)을 위해 존재하는 것이다.
과연 C/C++ 의 switch 구문은 어떤 방식으로 작동할까?
흔히 알려진 바로는 switch 구문이 if/else 비교 없이 해당 case 로 곧장 jump 하기 때문에 속도가 빠르다고 한다. 이것은 부분적으로 사실이다. 컴파일러가 이런 방식을 사용하게 된 것은 DOS 시절의 WATCOM C 부터였다고 한다.
프로그래머라면 생각해보자. 비교할 값만으로 jump 하려면 Address table 이 필요하다. 과연 Address table 만으로 switch 구문을 비교 없이 jump 하도록 구성할 수 있을까? 오래 생각하지 말자. 당연히 불가능하다.
32bit 플랫폼에서 int 는 4Giga 의 범위를 갖는다. Address point 도 4bytes 일 경우 Address table 은 최대 16GB 의 메모리를 사용할 수도 있다. (case 0, case 0xFFFFFFFF)
이에 대한 해답은. 바로 '조합' 이다.
즉, 연속적이거나 집적된 case 의 경우에는 해당 범위만큼의 테이블을 만들어 jump 하고 듬성듬성 떨어져 있는 case 의 경우는 if/else 를 이용하여 case 수 만큼 비교후 분기하는 것이다.
VC++ 6.0 과 7.0 의 디스어셈블리 기능을 이용해 분석해본바에 의하면 switch 구문은 다음과 같은 규칙을 갖고 기계어를 생성한다.
1. case 가 3개 이하인 경우에는 if/else 로 일일히 비교후 분기 한다.
2. case 가 4개 이상이고, 최소 case 와 최대 case 의 차이가 254 이하인 경우에는 Address table 을 만들어 jump 한다. (이 과정에서 최대 약 1KB 의 Address table 이 생성된다. switch 를 잘못 쓰면 1KB 의 디스크 공간과 메모리를 낭비할 수도 있다)
3. 최소 case 와 최대 case 의 차이가 255 이상인 경우에는 if/else 로 비교후 분기한다. 단, 최소 case 를 포함하며 규칙2의 조건을 만족하는 부분집합이 존재할 경우 해당 case 들은 Address table 을 만들어 jump 한다.
예>
case 0, 1, 2 -> if/else 로 분기 (규칙 1)
case 0, 1, 2, 3, 4 -> Address table 로 분기 (규칙2)
case 0, 1, 2, 3, 4, 100 -> Address table 로 분기 (규칙 2)
case 0, 1, 2, 3, 4, 100, 300 -> 0~100 까지는 Address table 로 분기. 300 은 if/else 로 분기(규칙3)
case 0, 300, 301, 302, 303, 304 -> 모두 if/else 로 분기 (규칙3)
이 외에도 몇 가지 규칙이 더 있을것으로 보인다. 하지만 이것 만으로도 벌써 switch 구문을 효과적으로 활용하기 위한 제한사항들이 머리속에 마구 떠오를 것이다. (5번째 예와 같이 구성해서는 안될것이다)
이런 작은 차이로부터 우리는 명품을 끌어낸다
반응형
'지식의 방' 카테고리의 다른 글
하버드식 동기부여 영상(harvard motivation movie)korea ver (0) | 2013.02.16 |
---|---|
아름다운 순우리말 100가지 (0) | 2011.04.30 |
Power English를 청취하기 위하여 녹음하기! (0) | 2010.12.28 |
Nokia N5800 XpressMusic 기기내 정보 확인 (0) | 2010.07.09 |
N5800 네스팟 이용하기 (0) | 2010.07.09 |
[펌]쿨가이를 위한 와인 생활백서 (1) | 2009.12.30 |
[자동 시간 관리 시스템] Autofocus Time Management System (2) | 2009.12.21 |
수도권 통합 요금제 (2) | 2009.12.08 |
네이버 POP3/SMTP 보안강화 공지문 (0) | 2009.11.03 |
프로젝트 개발단계.. (0) | 2009.01.08 |