switch vs if 어떤 때 어느게 효율적인가요?
글쓴이: sypark33 / 작성시간: 수, 2006/01/04 - 9:27오후
저는 조건문이 4개 이하이면 그냥 if, else if 로 하고, 그 이상이면 switch case 문을 사용하고 있습니다.
그냥 짧은 것은 switch문 쓰면 너무 소스가 길어져서..
그런데, 어떤게 어느때 사용해야 제대로 사용하는것인지 알고 싶더군요.
얼핏 들어본 기억으로는 ,
1. if문은 매번 조건문을 판단해야 하기에 switch문보다 느리다.
2. switch문은 case문 선별에 있에 stack에 값을 놓고 비교하기에, 느릴 수 있다..
뭐 이렇게 기억되는데 맞나요? embeded쪽이라 효율을 신경써야하는데, 이제껏 별 신경안쓰고 코딩하다가 문득 궁금합니다.
Forums:
Re: switch vs if 어떤 때 어느게 효율적인가요?
잘 아는 것은 아니지만...switch를 사용하는 것이 더 좋은 것으로 알고 있습니다.
모든 switch는 if로 표현가능하나 모든 if는 switch로 표현할 수 있는 건 아니죠.
컴파일러가 최적화할때 switch쪽이 더 유리한 것으로 알고 있습니다.
예를 들면 각 case의 위치를 미리 배열로 만들어 놓고 바로 해당 위치로 점프를 한다던지 하는 식도 있겠고요.
There is more than one way to do it...
저도 평소에 궁금해 하던 부분이어서[code:1]int m
저도 평소에 궁금해 하던 부분이어서
이런 소스를 짜놓고 vc 로 역어셈블 해봤습니다.
막연히 switch 가 if 문과 동일하지 않을까 생각했었는데 그게 아니었군요..
짧음
해당 구문은 Case 수가 적어서 별도로 최적화하지 않은겁니다. case가 10개를 넘어가면 다음처럼 최적화를 합니다.
https://godbolt.org/z/cb6T9zMvM
많은 구현체들이 switch 문을 jump table로 구현하기 때문에
많은 구현체들이 switch 문을 jump table로 구현하기 때문에 switch 문이 더 좋은
성능을 나타낼 때가 많습니다. 이 경우 레이블은 goto와 비슷한 성격을 갖게 되고요.
Duff's device는 이런 특성을 이용해서 최적화를 한 유명한 예입니다.
if문이 3개 일때까지는 더 빠르다고 들었었습니다.
if문이 3개 일때까지는 더 빠르다고 들었었습니다.
정확한 출처를 밝히라고 그러면.. 할말은 없습니다.
예전에 인터넷 어디선가 주워듣기로는 if문이 3개 이하라면
if문이 switch보다 더 빠르다고 들었습니다.
위키에 정리하는 게 어떨까요?
wiki:ZeroAsNull 처럼 정리할만한 내용이라고 생각합니다. 상당히 자주 거론되는 건데도 매번 이런저런 얘기만 듣고 뚜렷하게 정리해서 이해하지를 못하고 있네요.
switch 문의 최적화는 당연히 컴파일러마다 제각기 다르기 때문에 컴파
switch 문의 최적화는 당연히 컴파일러마다 제각기 다르기 때문에 컴파일러의 특성을 모르고 성급한 최적화를 하는 건 별로 바람직하지 않습니다. (jump table을 쓰는 경우에도 어떤 경우에 쓰고 어떤 경우에 안 쓰고 하는 기준이 다 지 맘대로입니다) 예를 들어서 제 기억이 맞다면 Visual C++는 300인가 그 이상의 값부터는 테이블을 안 쓴다던지 하는 얘기를 들은 것 같습니다. -_-
개인적으로는 연속된 값이 많이 나올 때 (특히 0에 가까운 수부터 시작할 때) switch를 선호합니다만 이건 취향이니 잘 모르겠습니다. 컴파일러랑 상관 없이 빠른 속도를 원한다면 직접 테이블을 만들어서 연결하는 방법이 가장 좋을 것이라 생각합니다. (call stack이 부담스럽다면 gcc extension 같은 걸 써서 라벨의 주소를 저장하는 방법도 있겠죠... ㅂㅌ is everywhere.)
제가 본 대부분의 switch 구현은 대충 이런 식으로 생겼습니다. 이 경우 0부터 N-1까지 case가 잡혀 있는 경우죠. (네 저 GAS 못 씁니다 -_-)
정확하게 기억은 안 나는데 x86의 경우 6클럭 아래로 소요될 겁니다. if가 3개 이하라면 switch보다 더 좋을 가능성이 높겠죠. 하지만 어디까지나 최적화 방법에 따라서 달라지므로 가급적이면 속도보다 가독성을 우선시해야 겠죠.
- 토끼군
switch문이 Jump table을 하는군요. 그렇다면 case 문이
switch문이 Jump table을 하는군요. 그렇다면 case 문이 작은 경우에는 jump table 구성하는데에 대한 오버헤드가 있을 수 있겠구요..
요즘 컴파일러는 똑똑해서...
switch문이 항상 jump table로 구현되는 것도 아니고...컴파일러에 따라 코드 상황에 따라 다릅니다.
저 정도 차이는 대부분의 PC에서 크리티컬한 성능의 차이를 보이지도 않고요..
성능보다는 의미를 생각해서 switch와 if를 구분해서 쓰는 것이 좋습니다.
그리고 보통은 switch쪽이 if보다 더 많은 의미를 가지고 있고요.
그렇게 생각한다면 switch가 적합할거처럼 보이는 곳은 switch로 하는 것이 좋습니다.
예를 들자면 하나의 상태변수가 있고 이 값에 따라 다르게 동작하고 상태가 true/false가 아닌 다양한 값을 가지는 경우는 switch로 쓰는게 맞겠죠.
There is more than one way to do it...
효율에 신경이 쓰여서 if/switch를 선택한다는 것은 너무 극단적인
효율에 신경이 쓰여서 if/switch를 선택한다는 것은 너무 극단적인 것 같습니다. 비록 if/switch가 메인 이벤트 루프에서 사용되더라도 if/switch의 차이보다는 다른 문제가 비효율의 주범일 가능성이 높다고 생각합니다.
임베디드쪽에선 극단적이 아닐수도 있지 않을까요?
어느 아키텍처마다 파이프라인을 사용하겠지만
RISC아키텍쳐의 경우는 if 같은 분기문으로 인하여 파이프라인이
깨어질경우 낭비되는 클럭이 40클럭 이상 되는경우도 있습니다.
그런걸 생각하면 결코 극단적이라고 말하긴 힘들거같은데요
========================================================
지하에서 땅파던 삽질마왕 지상에 출몰하다! ( ^-_-^)
대게 if문을 쓰게 되고, 3개 이상의 분기가 있을때 switch문을 보
대게 if문을 쓰게 되고, 3개 이상의 분기가 있을때 switch문을 보통 씁니다만,
저도 tokigun님처럼 가독성에 중점을 둡니다.
if을 쓰게 되느냐 switch문을 쓰게되느냐에 따라 나타나는 성능차이는 전체 프로그래밍 성능에 1%영향 미만일것이라 생각되는군요.
컴파일러 specific한 부분을 논외로 한다고 하면, 위에서 언급된것처럼 switch는 jump문인 것이고, if문보다 일반적으로 효율이 떨어집니다.
if문은 그 판단식이 복잡한 경우에 유용하고, switch문은 판단식이 단순할 경우 유용하고요.
판단식을 최대한 단순하게, if문을 줄이는 방향으로, 판단식이 매우 단순하고 if문을 줄이기 힘든 경우는 switch문으로
저도 컴파일러에 따라 어느 것이 좋은지가 달라진다고 생각합니다..같을
저도 컴파일러에 따라 어느 것이 좋은지가 달라진다고 생각합니다..
같을 수도 있구요..
아주 동작 시간에 민감한 경우가 아니면 이것으로 고민할 필요는 없을 것
같은데요.. 차이가 나도 많이 나진 않을테니까요..
같은 컴파일러라도 최적화 옵션에 따라 달라질지는 잘 모르겠습니다.
http://blog.dreamwiz.com/shjii
switch보다 if else를 선호하지만 switch문이 종종 유용하게
switch보다 if else를 선호하지만 switch문이 종종 유용하게
사용되는 경우가 있습니다.
예를 들어 어떤 사건(이벤트)에 따라 상태(플래그)값이 변경되고
그 상태값에따라 수행해야 할 로직이 다르다면 보통은 if문을 쓰게 될겁니다.
그런데 만약 상태값이 0일때 1, 2 상태의 로직도 수행해야 하고
상태값이 1 일때는 2 상태의 로직이 수행되어야 할 경우가 있습니다.
이런 비슷한 상황때문에 패턴이란게 있긴하지만 트릭을 쓰자면
switch문의 제어특성을 사용합니다.
만약 사용하는 언어에선 case문에 break를
반드시 사용해야 한다면 break 대신 goto문을 사용하면 됩니다.
compiler에 의한 jump table에 의미를 두기보다는 code
compiler에 의한 jump table에 의미를 두기보다는 code level에서 lookup table구축이 필요한 경우에 switch를 쓰고 있습니다.
if는 procedure의 sequence가 이어질 경우에 사용하고,
switch는 불규칙 bound가 발생하는 경우에 사용합니다.
대개 state machine의 경우인데, state간의 명확성이 모호해지는 것을 막기 위해 fall through는 안씁니다. 그럴바엔 그냥 한 state 내에 두는 편이 옳다고 생각합니다.
--------------------------------------------------------------------------------
\(´∇`)ノ \(´∇`)ノ \(´∇`)ノ \(´∇`)ノ
def ed():neTdiVeR in range(thEeArTh)
[quote="ed."]compiler에 의한 jump table에 의미
lookup table 구축이란 말과 한 state 내에 두는 편이 옳다는 말이 무슨 뜻인가요?
이곳의 많은 분들은 이해하셨겠지만..
저는 jump table을 의도하고 switch를 쓰는 일은 매우 어리석
저는 jump table을 의도하고 switch를 쓰는 일은 매우 어리석은 방법이라고 생각합니다. 그런 의도를 가졌으면 토끼군님이 글을 적으신 것 처럼 명시적으로 만드는 것이 올바릅니다.
명백한 의도를 가지고 있으면서 컴파일러의 최적화에 맞기는 우연에 맞기는 프로그램을 하는 것은 바른 자세가 아니라고 봅니다.
- 죠커's blog / HanIRC:#CN
댓글 달기