뻘글) 삼항연산자 vs if문, 누가 최적화를 더 잘해줄까?

JellyPower·2023년 5월 2일

뻘글

목록 보기
1/2

삼항연산자 쓰지 말아라?

  • 대학때 삼항연산자를 배우면서 교수님께서 삼항연산자를 쓰지 말라고 하셨던 기억이 난다. 그 이유는 코드의 빠르고 느리고를 떠나서 가독성이 좋지 않으니 쓰지 말라고 하셨다. 그리고 그 당시의 나는 그냥 그렇구나~ 하고 받아드렸었다.
  • 그리고 시간이 조금 지나 코딩의 ‘ㅋ’도 모르는 인큐베이터 안의 코딩 신생아 실력을 거쳐 인큐베이터에서 가까스로 벗어난 코딩 아가로 성장한 지금, 나는 삼항연산자를 쓰고있다. 그 이유는 그저 내가보기엔 삼항연산자의 가독성이 조금 더 좋았기 때문이다.
  • 복잡한 중첩if문같은 놈들이 아니면 if, else로 두 줄 쓸바에 한 줄에 작성하는게 더 보기 좋았고 그냥 그렇게 써오고 있다.
  • 그리고 나도 모르는 마음 한켠에는 뭔가 삼항연산자를 컴파일러가 더 잘 최적화 해주지 않을까 라는 생각이 있었다.
  • 왠지 그러지 않은가… 뭔가 언어에서 기초적으로 지원하는 연산자는 최적화의 대상이 되기 쉬울거 같고 if , else if처럼 cmp, jmp해야하는 부분들에 대해선 최적화가 쉽지 않을거같은… 그런… 객관적이지 않고 막연한 환상같은 마음을 품고있었다.
  • 그리고 그러한 환상을 품고 이를 증명해보고자 예제 코드를 한 번 짜보았다.
#include<cstdio>

#pragma optimize("", off)
int falseFunc() {
	printf("falseFunc works!\n");
	return 10;
}
#pragma optimize("", on)

int main() {
	bool myBool;
	int myInt;
	int trueValue = 20;

	scanf_s("%d", &myBool);
	

	
	if (myBool) myInt = trueValue;
	else myInt = falseFunc();
	printf("%d\n", myInt);
	
	myInt = myBool ? trueValue : falseFunc();
	printf("%d\n", myInt);
	
	return 0;
  • 예제 코드는 위와 같다.
  • 컴파일러가 최적화하기 쉽지 않도록 함수호출에 대해서만 최적화를 꺼서 함수가 inline되지 않게했고 true일때는 변수 대입, false일때는 함수 리턴값 대입을 진행하게 하여 최적화에 대한 의미분석을 나름 난해하게 만들어줬다.
  • 실험 환경은 msvc, x64, Release모드이다.

결론: 그런건 없다 코더야. ㅋㅋㅋ

myInt = myBool ? trueValue : falseFunc();
00007FF6F2241129  cmp         byte ptr [myBool],0  
00007FF6F224112E  je          main+36h (07FF6F2241136h)  
00007FF6F2241130  mov         eax,dword ptr [trueValue]  
00007FF6F2241134  jmp         main+3Bh (07FF6F224113Bh)  
00007FF6F2241136  call        falseFunc (07FF6F22410E0h)
00007FF7A6CD1129  cmp         byte ptr [myBool],0  
00007FF7A6CD112E  je          main+36h (07FF7A6CD1136h)  
00007FF7A6CD1130  mov         eax,dword ptr [trueValue]  
00007FF7A6CD1134  jmp         main+3Bh (07FF7A6CD113Bh)  
	else myInt = falseFunc();
00007FF7A6CD1136  call        falseFunc (07FF7A6CD10E0h)
  • 그 결과 코드는 위와 같다.
  • 결과는 완전 동일했다. 둘 다 똑같이 부울값을 비교하고 false면 함수호출로 바로 점프, true면 trueValue값을 레지스터에 바로 써주고 출력하는 방식으로 작동했다.
  • 물론, 컴파일러에 따라 최적화가 다를 순 있고 다양한 환경에서 실험해보지 않았지만 예제코드를 계속 짜보면서 어딜가나 같은 수준의 컴파일러 최적화면 다 도찐개찐으로 해줄거 같은 기분이 들었다.

우리 착한 코린이들은 그냥 가독성 따라 쓰도록 합시다.
전 그냥 간단한 구문이면 삼항연산자 쓸래요.

추신

  • 최대한 일반적인 환경을 가정하기 위해 컴파일러 최적화 옵션을 직접 꺼주는건 하지 않으려 했는데 엥간치 복잡하게 짜지 않는 이상 함수호출은 전부 인라인으로 박아주는거 보고 놀랐다.
  • 인라인 최적화 못하게 하려고 함수포인터를 파라미터로 받아서 해당 함수를 호출해주는 간단한 함수를 만들어서 썼는데도 그거조차 인라인으로 최적화해주는거 보고 놀랐다. msvc짱먹어라 짱짱
profile
게임엔진코드싸개(진)

1개의 댓글

comment-user-thumbnail
2024년 1월 7일

잘 보고 갑니다

답글 달기