if / switch-case

J·2024년 9월 6일

테스트

목록 보기
4/11
※ 개인적인 생각이 추가되어 정확하지 않은 정보일 수 있다.

switch - case문을 사용할 때 컴파일러의 재량에 따라 jump table이 생성될 수 있다고 한다.
그래서 테스트를 해봤다.

if문 테스트

#include <iostream>

void Func1() { int a = 34; int b = 342; int c = a + b; }
void Func2() { int a = 4; int b = 132; int c = b / a; }
void Func3() { int a = 3; int b = 465; int c = a * b; }
void Func4() { int a = 63; int b = 87; int c = a % b; }
void OtherFunc() { std::cout << "그 외..\n"; }

int main()
{
	int a = 5;

	if (a == 1)
	{
		Func1();
	}
	else if(a == 2)
	{
		Func2();
	}
	else if (a == 3)
	{
		Func3();
	}
	else if (a == 4)
	{
		Func4();
	}
	else
	{
		OtherFunc();
	}
	
}

if - else if문으로 실행을 시켰을 때 a값이 5가 맞을 때까지
비교하고 분기를 타는 [ cmp와 jne ]의 반복으로 이루어짐을 확인

그래서 위 코드를 switch-case 형태로 바꿔서 실행해보았다.

switch - case

#include <iostream>

void Func1() { int a = 34; int b = 342; int c = a + b; }
void Func2() { int a = 4; int b = 132; int c = b / a; }
void Func3() { int a = 3; int b = 465; int c = a * b; }
void Func4() { int a = 63; int b = 87; int c = a % b; }
void OtherFunc() { std::cout << "그 외..\n"; }
int main()
{
	int a = 4;

	switch (a)
	{
	case 1:
		Func1();
		break;
	case 2:
		Func2();
		break;
	case 3:
		Func3();
		break;
	case 4:
		Func4();
		break;
	case 5:
		std::cout << "dkfls\n";
		break;
	default:
		OtherFunc();
		break;
		
	}
	
}

1. 연속적일 때

case가 연속적일 때 case에 해당되는지 판단을 먼저 한 후 해당된다면 jumptable 을 생성 해 + index로 바로 점프할 수 있도록 하는 것을 보았다.

1-2

	switch (a)
	{
	case 2:
		Func2();
		break;
	case 4:
		Func4();
		break;
	case 1:
		Func1();
		break;
	case 5:
		std::cout << "dkfls\n";
		break;
	case 3:
		Func3();
		break;
	default:
		OtherFunc();
		break;
		
	}

의 경우에도 점프 테이블을 이용한다.

2. 연속적이지 않을 때

#include <iostream>

void Func1() { int a = 34; int b = 342; int c = a + b; }
void Func2() { int a = 4; int b = 132; int c = b / a; }
void Func3() { int a = 3; int b = 465; int c = a * b; }
void Func4() { int a = 63; int b = 87; int c = a % b; }
void OtherFunc() { std::cout << "그 외..\n"; }
int main()
{
	int a = 56;

	switch (a)
	{
	case 1:
		Func2();
		break;
	case 56:
		Func1();
		break;
	case 85:
		Func4();
		break;
	case 4243:
		std::cout << "dkfls\n";
		break;
	case 36463:
		Func3();
		break;
	default:
		OtherFunc();
		break;
		
	}
	
}  

case가 연속적으로 처리되지 않을 때는 맨 처음 0x55와 비교를 해서 그것보다 더 크다면 처음부터 작은 수와 cmp,je를 하지 않고 어느정도 큰 수와 먼저 비교될 수 있도록 하는 로직이 들어가있는 것 같다.

다만,
case가 4개 이상이어야 컴파일러는 jump table을 생성해서 활용하는 것 같다.

#include <iostream>

void Func1() { int a = 34; int b = 342; int c = a + b; }
void Func2() { int a = 4; int b = 132; int c = b / a; }
void Func3() { int a = 3; int b = 465; int c = a * b; }
void Func4() { int a = 63; int b = 87; int c = a % b; }
void OtherFunc() { std::cout << "그 외..\n"; }
int main()
{
	int a = 4;

	switch (a)
	{
	case 1:
		Func1();
		break;
	case 2:
		Func2();
		break;
	case 3:
		Func3();
		break;
	default:
		OtherFunc();
		break;

	}
}

다음과 같은 상황에서는 cmp, je를 활용하는 것이 더 효율적이라고 판단하는 것 같다.

결론

if - else if나 switch - case나 도토리 키재기 같은데..만약 case가 가지런히 놓여서 사용될 때 (점프 테이블을 생성해서 이용할 때)라면 switch_case가 조금은 더 괜찮게 사용되지 않을까 싶다.

profile
낙서장

0개의 댓글