※ 대부분에 언어에 해당될 수 있는 내용이지만, javascipt 언어에 가장 적합한 글입니다.
0. 방법이 바뀐다고 조건문의 성능 차이가 있을까?
조건문에는 <if/else> 문도 있지만 <switch/case> 문도 있다. 개인적으로 이 둘의 '가독성' 차이는 별로 없다고 생각한다. 취향 차이가 있을 뿐이지 두 조건문 방법 모두 충분히 좋은 조건문이라 보인다. 위 주장이 맞기 위해서는 조건문 방법이 달라진다고 '성능' 차이는 크게 발생하지 않는다라는 전제가 있어야 한다.
하지만 <switch/case> 문 성능이 우수하다는 의견이 많았고 정말 그러하다면 '좋은 조건문'에 대하여 다시 한번 생각해볼 문제라고 생각했다.
그래서 특별히 <switch/case> 문의 성능을 들여다보게 되었다.
1. <switch/case> 문은 무엇이 특별한가?
한 블로거께서 다음과 같이 표현해주셨다.
if-else문은 원하는 조건이 나올 때까지 순차적으로 모든 경우를 비교하지만 switch문은 jump-table을 사용해서 한 번에 원하는 곳에 이동한다
출처: https://wecansoar.tistory.com/27
한 블로거께서는 다음과 같이 표현해주셨다.
if-else-if의 단점은 조건을 다 확인한다는 거예요... switch 식은 한 번 평가됩니다.
출처: https://lim2j.tistory.com/135
한 번에 원하는 곳으로 이동한다는 말과 한 번 평가된다는 말이 안 와닿을 수 있는데, 이는 디버깅을 해보면 확실하게 알 수 있다. 과일 이모지를 가져오는 함수인데, 가장 마지막 조건인 'lemon'을 가져오는 테스트를 해보았다.
보니 확실하게 이해가 된다.
(어쩌면 디버깅의 이점이 있을 수도 있겠다는 생각은 들었다.)
이러한 이유로 속도의 차이도 발생하는 것인가?라는 물음이 생겼다.
2. <switch/case> 문은 엄청 빠른가?
6개의 분기가 존재하는 위 과일 이모지를 가져오는 함수를 <console.time> 문으로 타임 체크했다.
조건문 | 10,000번 | 100번 | 1번 |
<switch/case>문 | 평균 1ms | 평균 0.1ms | 평균 0.1ms 이하 |
<if/else>문 | 평균 1ms | 평균 0.1ms | 평균 0.1ms 이하 |
1번 한다고, 100번 한다고 큰 차이는 없었고, 10,000번 하면 전체적으로 조금 시간이 더 걸리는 편이었으나 역시나 차이는 없었다. 혹시 분기가 적어서는 아닐까 싶어, 6개에서 20개로 늘려보았지만 역시나 차이는 없었다. 보기에는 조건 비교가 많아져 성능상 차이가 클 수도 있겠다는 생각이 들었지만 전혀 아니었다.
3. <switch/case> 문의 단점 극복하기? switch(true)
if 문을 switch 문으로 변환할 수 있고, switch 문을 if 문으로 변환할 수 있지만 '모든' if의 문장을 switch로 바꿀 수는 없다.
출처 : https://itbeginner2020.tistory.com/19
위 명제를 만족시키는 코드를 보자.
function getMinNumber(n) {
if (n >= 0 && n < 10) {
return 0;
} else if (n >= 10 && n < 20) {
return 10;
} else if (n >= 20 && n < 30) {
return 20;
} else if (n >= 30 && n < 40) {
return 30;
} else {
return 0;
}
}
function getMinNumber(n) {
switch (n) {
case ? :
}
}
아래의 <switch/case> 문에서 case는 동등 비교에 해당하는 값을 넣는 것이기 때문에 동등 비교가 아닌 로직을 처리하기에는 어려움이 있다. javascript 언어에서 case 문에 값이 아닌 식도 작성할 수 있기 때문에 응용하면 동등 비교가 아니더라도 <switch/case> 문을 실행할 수 있다.
function getMinNumber(n) {
switch (true) {
case (n >= 0 && n < 10) :
return 0;
case (n >= 10 && n < 20) :
return 10;
case (n >= 20 && n < 30) :
return 20;
case (n >= 30 && n < 40) :
return 30;
default :
return 0;
}
}
위처럼 응용하면 또 다른 방법으로 조건문을 시도해볼 수 있다.
이렇게 했을 때 디버깅을 해보면 기존 <switch/case> 문 특징을 그대로 가져간다. 디버깅에 확실히 장점이 있어 보인다.특히, 'OR' 조건이 많은 경우에는 확실히 가독성이 좋은 것으로 보인다. ★★★
function testIf(user) {
if (user.age > 40 || user.name.startsWith('B') || (user.name === 'Sam' && user.age === 31) || (user.name === 'Alice' && user.age === 28)) {
return `Welcome ${user.name}!`;
}
return 'Welcome unknown user';
}
function testSwitch(user) {
switch (true) {
case user.age > 40:
case user.name.startsWith('B'):
case user.name === 'Sam' && user.age === 31:
case user.name === 'Alice' && user.age === 28:
return `Welcome ${user.name}!`;
default:
return 'Welcome unknown user';
}
}
※ 참고한 포스트 : https://ui.toast.com/weekly-pick/ko_20210603
<if/else> 문과는 색다른 매력이 있는 <switch/case> 문을 때때로 조건문으로 활용해보면 좋을 것 같다.
'Deep Dive Series > Good Condition' 카테고리의 다른 글
[좋은 조건문 작성하기 4] JSON 객체를 활용한 조건문 형태 (0) | 2022.02.20 |
---|---|
[좋은 조건문 작성하기 3] 애매한 조건문은 팀원들과 생각 나누기 (0) | 2022.01.08 |
[좋은 조건문 작성하기 1] Early Return은 깊이가 얕아서 좋다! (0) | 2021.12.05 |
[좋은 조건문 작성하기 0] 왜 좋은 조건문을 작성해야 할까? (0) | 2021.12.02 |