C # switch 문과 CIL switch 명령을 혼동하지 않는 것이 중요합니다.
CIL 스위치는 점프 테이블이므로 점프 주소 세트에 대한 색인이 필요합니다.
이것은 C # 스위치의 케이스가 인접한 경우에만 유용합니다.
case 3: blah; break;
case 4: blah; break;
case 5: blah; break;
그러나 그렇지 않은 경우 거의 사용하지 않습니다.
case 10: blah; break;
case 200: blah; break;
case 3000: blah; break;
(3 개의 슬롯 만 사용하여 ~ 3000 개의 테이블 크기 항목이 필요합니다)
인접하지 않은 표현식을 사용하면 컴파일러는 선형 if-else-if-else 검사를 수행하기 시작할 수 있습니다.
인접하지 않은 더 큰 표현식 세트를 사용하면 컴파일러는 이진 트리 검색으로 시작하여 마지막으로 몇 개의 항목 만 if-else-if-else로 시작할 수 있습니다.
인접한 항목의 덩어리를 포함하는 표현식 세트를 사용하면 컴파일러는 이진 트리 검색과 마지막으로 CIL 스위치를 사용할 수 있습니다.
이것은 "mays"& "mights"로 가득 차 있으며 컴파일러에 따라 다릅니다 (Mono 또는 Rotor와 다를 수 있음).
인접한 경우를 사용하여 결과를 컴퓨터에 복제했습니다.
10 웨이 스위치를 실행하는 총 시간, 10000 회 반복 (ms) : 25.1383
10 웨이 스위치 당 대략적인 시간 (ms) : 0.00251383
50 웨이 스위치를 실행하는 총 시간, 10000 회 반복 (ms) : 26.593
50 웨이 스위치 당 대략적인 시간 (ms) : 0.0026593
5000 웨이 스위치를 실행하는 총 시간, 10000 반복 (ms) :
5000 웨이 스위치 (ms) 당 대략적인 시간 : 23.7094 : 0.00237094
50000 웨이 스위치를 실행하는 총 시간, 10000 반복 (ms) : 205000 년
스위치 (ms) 당 대략적인 시간 : 0.00200933
그런 다음 인접하지 않은 케이스 표현식을 사용했습니다.
10 웨이 스위치를 실행하는 총 시간, 10000 회 반복 (ms) : 19.6189
10 웨이 스위치 당 대략적인 시간 (ms) : 0.00196189
500 웨이 스위치를 실행하는 총 시간, 10000 반복 (ms) : 19.1664
500 웨이 스위치 (ms) 당 대략적인 시간 : 0.00191664
5000 웨이 스위치를 실행하는 총 시간, 10000 반복 (ms) :
5000 웨이 스위치 (ms) 당 대략적인 시간 : 19.5871 : 0.00195871
인접하지 않은 50,000 개의 case switch 문은 컴파일되지 않습니다.
"표현식이 너무 길거나 복잡하여 'ConsoleApplication1.Program.Main (string [])'근처에서 컴파일 할 수 없습니다.
여기서 재미있는 점은 이진 트리 검색이 CIL 스위치 명령보다 약간 (통계적으로는 그렇지 않음) 빠르다는 것입니다.
Brian, " constant " 라는 단어를 사용했는데 , 이는 계산 복잡도 이론 관점에서 매우 명확한 의미를 갖습니다. 단순한 인접 정수 예제는 O (1) (일정)로 간주되는 CIL을 생성 할 수 있지만, 드문 예제는 O (log n) (대수)이며 군집 된 예제는 중간에 있고 작은 예제는 O (n) (선형)입니다. ).
이것은 정적을 Generic.Dictionary<string,int32>
만들 수있는 String 상황을 다루지 않으며 처음 사용할 때 명확한 오버 헤드를 겪게됩니다. 여기서의 성능은의 성능에 따라 다릅니다 Generic.Dictionary
.
CIL 사양이 아닌 C # 언어 사양 을 확인하면 "15.7.2 switch statement"에 "일정한 시간"에 대한 언급이 없거나 기본 구현에서 CIL 스위치 명령어를 사용하기도합니다 (매우 신중하게 가정해야 함). 그런 것들).
하루가 끝나면 현대 시스템의 정수 식에 대한 C # 스위치는 마이크로 초 미만의 작업이며 일반적으로 걱정할 필요가 없습니다.
물론이 시간은 기계와 조건에 따라 다릅니다. 이 타이밍 테스트에주의를 기울이지 않을 것입니다. 우리가 말하는 마이크로 초의 지속 시간은 실행중인 "실제"코드로 인해 난장이입니다 (그리고 "실제 코드"를 포함해야합니다. 그렇지 않으면 컴파일러가 분기를 최적화합니다). 시스템의 지터. 내 대답은 IL DASM 을 사용 하여 C # 컴파일러로 만든 CIL을 검사 한 결과입니다. 물론 CPU가 실행하는 실제 명령어는 JIT에 의해 생성되므로 최종적인 것은 아닙니다.
x86 컴퓨터에서 실제로 실행되는 최종 CPU 명령어를 확인했으며 다음과 같은 간단한 인접 세트 스위치를 확인할 수 있습니다.
jmp ds:300025F0[eax*4]
이진 트리 검색이 가득한 경우 :
cmp ebx, 79Eh
jg 3000352B
cmp ebx, 654h
jg 300032BB
…
cmp ebx, 0F82h
jz 30005EEE