문제의 발단 : 내가 원래 쓰던 c++은 string에 대하여 switch문을 사용할 수가 없었다.
switch() 안에 int 형의 변수만 들어갈 수 있다 보니까 여러 String 조건에 대하여 if else 지옥을 만들지 않으려면 Map<string,int> 와 같은 방식으로, 문자열 조건을 정수로 바꿔주는
mapper를 만들어서 switch문을 썼어야만 했었다.
예를 들면 아래와 같은 코드로
Map<String, Integer> map = new HashMap<>();
for(int i =1 ; i < 13; i++){
map.put("string" + i, i); // 문자열과 정수 매핑
}
for(int i = 0 ; i < 100000000; i++){
switchInt(map.get("string1"));
}
근데 java는 switch 안에 문자열을 넣을 수 있다고 하네?? 신기하다
그래서 겸사겸사 성능 테스트를 해봤다.
switch문을 1억번씩 돌릴건데,
- swtich int로 첫번째 케이스에서 return되는 경우
- swtich int로 12번째 케이스에서 return되는 경우
- swtich String으로 첫번째 케이스에서 return되는 경우
- swtich String으로 12번째 케이스에서 return되는 경우
- mapper를 활용해서 switch int로 첫번째 케이스에서 return되는 경우
- mapper를 활용해서 switch int로 12번째 케이스에서 return되는 경우
- if 문으로 첫번째 케이스에서 return 되는 경우
- if 문으로 12 번째 케이스에서 return 되는 경우
다 돌려본 결과 돌릴 때 마다 차이가 있긴 하지만
위와 같은 결과를 얻었다.
int vs String은 100배정도의 차이, mapper를 활용하면 오히려 String switch 할때보다 두배나 더 걸렸다. mapper는 안되겠다…
추가로, if문이나 switch문이나 조건 분기가 엄청 많지 않으면, 크게 차이나지 않는 것 같다. 테스트 상황에서는 12번째 조건에서 hit될 경우 if문이 switch문보다 두배 정도 더 걸렸다.
package org.example;
import java.util.*;
public class test {
static class Timer{
long start;
public void start(){
start = System.currentTimeMillis();
}
public void end(String task){
System.out.println(task + " : " + (System.currentTimeMillis() - start)/(double) 1000);
}
}
public static int switchString(String str){
switch(str){
case "string1":
return 1;
case "string2":
return 2;
case "string3":
return 3;
case "string4":
return 4;
case "string5":
return 5;
case "string6":
return 6;
case "string7":
return 7;
case "string8":
return 8;
case "string9":
return 9;
case "string10":
return 10;
case "string11":
return 11;
case "string12":
return 12;
default:
return 1;
}
}
public static int switchInt(int value){
switch(value){
case 1:
return 1;
case 2:
return 2;
case 3:
return 3;
case 4:
return 4;
case 5:
return 5;
case 6:
return 6;
case 7:
return 7;
case 8:
return 8;
case 9:
return 9;
case 10:
return 10;
case 11:
return 11;
case 12:
return 12;
default:
return 0;
}
}
public static int ifInt(int value){
if(value == 1)
return 1;
else if(value == 2)
return 2;
else if(value == 3)
return 2;
else if(value == 4)
return 2;
else if(value == 5)
return 2;
else if(value == 6)
return 2;
else if(value == 7)
return 2;
else if(value == 8)
return 2;
else if(value == 9)
return 2;
else if(value == 10)
return 2;
else if(value == 11)
return 2;
else if(value == 12)
return 2;
return 0;
}
public static void main(String[] args) {
Timer timer = new Timer();
Map<String, Integer> map = new HashMap<>();
for(int i =1 ; i < 13; i++){
map.put("string" + i, i);
}
timer.start();
for(int i = 0 ; i < 100000000; i++){
switchInt(1); // switch 첫번째 hit
}
timer.end("int switch 첫번 째 hit");
timer.start();
for(int i = 0 ; i < 100000000; i++){
switchInt(1); // switch 첫번째 hit
}
timer.end("int switch 첫번 째 hit");
timer.start();
for(int i = 0 ; i < 100000000; i++){
switchInt(12); // switch 6번째 hit
}
timer.end("int switch 12번 째 hit");
timer.start();
for(int i = 0 ; i < 100000000; i++){
switchString("string1"); // switch 첫번째 hit
}
timer.end("String switch 첫번 째 hit");
timer.start();
for(int i = 0 ; i < 100000000; i++){
switchString("string12"); // switch 6번째 hit
}
timer.end("String switch 12번 째 hit");
timer.start();
for(int i = 0 ; i < 100000000; i++){
switchInt(map.get("string1")); // mapper 활용한 switch 첫번째 hit
}
timer.end("mapper 활용한 int switch 첫번 째 hit");
timer.start();
for(int i = 0 ; i < 100000000; i++){
switchInt(map.get("string12")); // mapper 활용한 switch 12번째 hit
}
timer.end("mapper 활용한 int switch 12번 째 hit");
timer.start();
for(int i = 0 ; i < 100000000; i++){
ifInt(1); // mapper 활용한 switch 12번째 hit
}
timer.end("보너스 int if문 1번째 hit");
timer.start();
for(int i = 0 ; i < 100000000; i++){
ifInt(12); // mapper 활용한 switch 12번째 hit
}
timer.end("보너스 int if문 12번째 hit");
}
}