답변:
컴파일러는 해당되는 경우 점프 테이블을 빌드 할 수 있습니다. 예를 들어 리플렉터를 사용하여 생성 된 코드를 살펴보면 문자열의 큰 스위치에 대해 컴파일러가 실제로 해시 테이블을 사용하여이를 디스패치하는 코드를 생성한다는 것을 알 수 있습니다. 해시 테이블은 문자열을 키로 사용하고 case
코드를 값으로 위임 합니다.
이것은 많은 체인 if
테스트 보다 점근 적으로 더 나은 런타임을 가지며 실제로 상대적으로 적은 문자열에서도 더 빠릅니다.
이것은 if..else if ..
사람에 의해 사소하게 switch 문으로 변환 될 수 있는 시퀀스 를 만나는 현대 컴파일러처럼 약간 단순화 된 것입니다. 컴파일러도 마찬가지입니다. 그러나 재미를 더하기 위해 컴파일러는 구문에 의해 제한되지 않으므로 범위, 단일 대상 등이 혼합 된 내부적으로 "switch"와 같은 명령문을 생성 할 수 있으며 switch와 if 모두에 대해이 작업을 수행 할 수 있습니다. .else 문.
Anyhoo, Konrad의 답변에 대한 확장은 컴파일러가 점프 테이블을 생성 할 수 있지만 반드시 보장되는 것은 아닙니다 (바람직하지 않음). 다양한 이유로 점프 테이블은 최신 프로세서의 분기 예측 자에 나쁜 일을하고 테이블 자체는 행동을 캐시하기 위해 나쁜 일을합니다.
switch(a) { case 0: ...; break; case 1: ...; break; }
컴파일러가 실제로 이에 대한 점프 테이블을 생성했다면 점프 테이블이 if..else if..
분기 예측을 무너 뜨리기 때문에 대체 스타일 코드 보다 느릴 수 있습니다 .
Switch / case 문은 일반적으로 1 단계 깊이에서 더 빠를 수 있지만 2 개 이상을 시작하면 switch / case 문이 중첩 된 if / else 문보다 2-3 배 오래 걸리기 시작합니다.
이 기사에는 이러한 문이 중첩 될 때 속도 차이를 강조하는 몇 가지 속도 비교 가 있습니다.
예를 들어 테스트에 따르면 다음과 같은 샘플 코드가 있습니다.
if (x % 3 == 0)
if (y % 3 == 0)
total += 3;
else if (y % 3 == 1)
total += 2;
else if (y % 3 == 2)
total += 1;
else
total += 0;
else if (x % 3 == 1)
if (y % 3 == 0)
total += 3;
else if (y % 3 == 1)
total += 2;
else if (y % 3 == 2)
total += 1;
else
total += 0;
else if (x % 3 == 2)
if (y % 3 == 0)
total += 3;
else if (y % 3 == 1)
total += 2;
else if (y % 3 == 2)
total += 1;
else
total += 0;
else
if (y % 3 == 0)
total += 3;
else if (y % 3 == 1)
total += 2;
else if (y % 3 == 2)
total += 1;
else
total += 0;
동등한 switch / case 문을 실행하는 데 걸린 시간의 절반으로 완료되었습니다 .
switch (x % 3)
{
case 0:
switch (y % 3)
{
case 0: total += 3;
break;
case 1: total += 2;
break;
case 2: total += 1;
break;
default: total += 0;
break;
}
break;
case 1:
switch (y % 3)
{
case 0: total += 3;
break;
case 1: total += 2;
break;
case 2: total += 1;
break;
default: total += 0;
break;
}
break;
case 2:
switch (y % 3)
{
case 0: total += 3;
break;
case 1: total += 2;
break;
case 2: total += 1;
break;
default: total += 0;
break;
}
break;
default:
switch (y % 3)
{
case 0: total += 3;
break;
case 1: total += 2;
break;
case 2: total += 1;
break;
default: total += 0;
break;
}
break;
}
예, 이것은 초보적인 예이지만 요점을 보여줍니다.
따라서 결론은 한 레벨 깊이의 단순 유형에 대해 스위치 / 케이스를 사용하는 것일 수 있지만 더 복잡한 비교 및 다중 중첩 레벨의 경우 클래식 if / else 구문을 사용합니까?