사용하는 장점 / 단점은 무엇입니까 switch
대 문을 if/else
C #에서이. 코드의 모양 이외의 다른 점이 있다고 상상할 수 없습니다.
결과 IL 또는 관련 런타임 성능이 근본적으로 다른 이유가 있습니까?
관련 : 문자열을 켜거나 다른 유형을 입력하는 것이 더 빠릅니까?
답변
SWITCH 문은 디버그 또는 호환성 모드의 IF와 동일한 어셈블리 만 생성합니다. 릴리스에서는 O (1) 인 MSIL ‘switch’문을 통해 점프 테이블로 컴파일됩니다.
C # (다른 많은 언어와 달리)은 문자열 상수를 켤 수 있으며 약간 다르게 작동합니다. 임의 길이의 문자열에 대한 점프 테이블을 작성하는 것은 실용적이지 않으므로 대부분의 경우 이러한 스위치는 IF 스택으로 컴파일됩니다.
그러나 오버 헤드를 처리 할 수있는 조건 수가 충분하면 C # 컴파일러는 HashTable 개체를 만들고 문자열 상수로 채우고 해당 테이블을 조회 한 다음 점프합니다. 해시 테이블 조회는 엄격하게 O (1)가 아니며 눈에 띄는 일정한 비용이 있지만 대소 문자 레이블 수가 많으면 IF의 각 문자열 상수와 비교할 때보 다 훨씬 빠릅니다.
요약하면 조건 수가 5 이상인 경우 IF보다 SWITCH를 선호하고 그렇지 않으면 더 나은 것을 사용하십시오.
답변
일반적으로 (모든 언어와 모든 컴파일러를 고려하면) 스위치 문은 컴파일러가 스위치 문에서 점프 테이블을 생성하기 쉽기 때문에 if / else 문보다 더 효율적일 수 있습니다. 적절한 제약 조건이 주어지면 if / else 문에 대해 동일한 작업을 수행 할 수는 있지만 훨씬 더 어렵습니다.
C #의 경우에도 마찬가지이지만 다른 이유로도 마찬가지입니다.
많은 수의 문자열을 사용하면 컴파일러에서 해시 테이블을 사용하여 점프를 구현하므로 switch 문을 사용하면 성능이 크게 향상됩니다.
적은 수의 문자열을 사용하면 둘 사이의 성능이 동일합니다.
이 경우 C # 컴파일러는 점프 테이블을 생성하지 않기 때문입니다. 대신 IF / ELSE 블록과 같은 MSIL을 생성합니다.
jitted가 점프 테이블을 사용하여 스위치 명령문을 구현하는 “스위치 명령문”MSIL 명령이 있습니다. 그러나 정수 유형에서만 작동합니다 (이 질문은 문자열에 대해 묻습니다).
적은 수의 문자열의 경우 컴파일러가 IF / ELSE 블록을 생성하는 것이 더 효율적이며 해시 테이블을 사용하는 것입니다.
처음에 이것을 알았을 때 IF / ELSE 블록이 적은 수의 문자열과 함께 사용 되었기 때문에 컴파일러는 많은 수의 문자열에 대해 동일한 변환을 수행했다고 가정했습니다.
이것은 잘못되었습니다. ‘IMA’는 이것을 나에게 지적하기에 충분히 친절했습니다 (음. 그는 친절하지 않았지만 그는 옳았습니다.
또한 MSIL에 “스위치”명령이 없다는 것에 대한 본론을 세웠습니다 (스위치 기본 요소가있는 경우 해시 테이블과 함께 사용하지 않은 이유를 알았으므로 스위치 기본 요소가 없어야합니다. …). 이것은 모두 틀렸고, 엄청나게 바보였습니다. 다시 ‘IMA’가 이것을 지적했습니다.
가장 높은 등급의 게시물이기 때문에 여기에서 업데이트했으며 허용되는 답변입니다.
그러나 REP가 잘못되었다고 생각하지 않기 때문에 Community Wiki로 만들었습니다. 기회가 생기면 투표 ‘ima’의 게시물을 올리십시오.
답변
선호하는 세 가지 이유 switch
:
-
네이티브 코드를 대상으로하는 컴파일러는 종종 switch 문을 하나의 조건부 분기와 간접 점프 로 컴파일 할 수 있지만
if
s 시퀀스 에는 일련의 조건부 분기 가 필요합니다 . 사례의 밀도에 따라 사례 진술을 효율적으로 컴파일하는 방법에 대해 많은 학습 논문이 작성되었습니다. 일부는 lcc 컴파일러 페이지 에서 링크됩니다 . (Lcc는 스위치를위한 더 혁신적인 컴파일러 중 하나를 가졌습니다.) -
switch 문은 상호 배타적 인 대안 중에서 선택 되며 스위치 구문 은이 제어 흐름을 프로그래머에게보다 투명하게 만들고 if-then-else 문의 중첩을 만듭니다.
-
ML 및 Haskell을 포함한 일부 언어에서는 컴파일러가 사례를 생략했는지 확인합니다 . 이 기능을 ML 및 Haskell의 주요 장점 중 하나로 생각합니다. C #이 이것을 할 수 있는지 모르겠습니다.
일화 : 평생 공로상을 수상한 강연에서 Tony Hoare가 자신의 경력에서 한 모든 일에 대해 가장 자랑스럽게 생각하는 세 가지가 있다고 들었습니다.
- 퀵소트 발명
- 스위치 문 발명 (토니가
case
명령문을 ) - 업계에서 경력을 시작하고 끝내기
나는 없이 사는 상상할 수 없습니다switch
.
답변
컴파일러는 약간의 차이 (Knuth, anyone?)를 사용하여 거의 모든 것을 동일한 코드로 최적화 할 것입니다.
차이점은 switch 문이 다른 문을 함께 묶으면 15 개보다 깨끗하다는 것입니다.
친구는 친구가 if-else 문을 쌓아 두지 못하게합니다.
답변
실제로 switch 문이 더 효율적입니다. 컴파일러는 if / else 문으로는 찾을 수없는 조회 테이블에 최적화합니다. 단점은 switch 문을 변수 값과 함께 사용할 수 없다는 것입니다.
당신은 할 수 없습니다 :
switch(variable)
{
case someVariable
break;
default:
break;
}
그건 그래야만 해
switch(variable)
{
case CONSTANT_VALUE;
break;
default:
break;
}
답변
나는 다른 사람이 스위치 진술의 가정 된 효율성 이점이 거의 똑같이 가능성이있는 다양한 경우에 달려 있다고 (명백한?) 지점을 제기하는 것을 보지 못했습니다. 값 중 하나 (또는 몇 개)가 훨씬 가능성이 높은 경우 가장 일반적인 경우를 먼저 확인하여 if-then-else 래더가 훨씬 빠릅니다.
예를 들어,
if (x==0) then {
// do one thing
} else if (x==1) {
// do the other thing
} else if (x==2) {
// do the third thing
}
vs
switch(x) {
case 0:
// do one thing
break;
case 1:
// do the other thing
break;
case 2:
// do the third thing
break;
}
x가 시간의 90 % 인 경우 “if-else”코드는 스위치 기반 코드보다 두 배 빠릅니다. 컴파일러가 “스위치”를 일종의 영리한 테이블 기반 goto로 바꾸어도 단순히 0을 확인하는 것만 큼 빠르지는 않습니다.
답변
종종 더 좋아 보일 것입니다. 즉, 진행 상황을 이해하기가 더 쉬울 것입니다. 성능상의 이점이 최소한으로 최소화 될 것이라는 점을 고려하면 코드보기가 가장 중요한 차이점입니다.
따라서 if / else가 더 좋아 보인다면 사용하고 그렇지 않으면 switch 문을 사용하십시오.