뭐 설명이 예시가 들어가게 돼서 좀 허접해 보이긴 하는데 cpu는 뺄 샘이라는 연산이 불가능하기 때문에 이런 방식을 쓴다 정도로만 이해해주셔도 좋을 것 같습니다.
음... 비트 연산도 매우 중요합니다.
하지만 속도가 빨라지게 하기 위해서 곱셈, 나눗셈 연산을 쉬프트 연산으로 쓰거나 이런 행동은 하지 마세요 어차피 티 도안 나는 시간 차이가 나는 거니까요.
그리고 sizeof연산자인데요... 이건 그냥 상수 치환 문입니다.. 그냥 들어온 타입에 대해서 사이즈를 뱉어내는 기능입니다. 그 이상도 이하도 아닙니다..
그리고 if문에 대한 얘기를 좀 해보려고 합니다
if문에 논리 연산자가 들어가게 된다면
&& 연산자의 경우에는 false가 나올 확률이 높은 것을 앞에 두는 것이 좋습니다. 왜냐면 앞이 true인데 뒤가 false이면 연산 낭비니까요
반대로 || 연산자의 경우에는 true가 나올 확률이 높은 것을 앞에 두는 것이 좋습니다. 위와 똑같은 이유로 앞이 false인데 뒤가 true가 나오면 앞의 연산은 시간낭비가 되니까요...
그리고 if문의 신기한 점은 우리는 분명 조건을 a == b라고 걸지만 컴파일러는 반대로 해석한다는 점 알고 계신가요?
a와 b가 다르면 if문을 스킵하는 방향으로 어셈블리를 뽑아준답니다~ 정말 신기하죠ㅋㅋㅋ 허허... 저만 신기한가요
a < b 이면 a>= b를 체크한 다음 스킵하는 방향으로 어셈블리를 뽑아버린다는 거...\
사진에서 보시면 jne jump not equal의 약자입니다.
동일하지 않으면 그냥 점프해서 스킵해버려라라고 어셈블리를 뽑아주는군요 정말...
네 뭐 그렇다고요 다음으로 넘어가겠습니다
많은 분들이 if -> else if -> else if -> else 문이 좋으냐 아니면 switch가 좋으냐에 대해서 궁금해하시더라고요.
음... 결론부터 말씀드리자면 switch가 더 좋을 확률이 있습니다라고 말씀을 드려야 될 것 같습니다.
이유가 if문을 쭉 길게 나열하게 된다면 cmp jump cmp jump cmp jump를 통해 계속 분기를 타는 문장이 나오게 되는데요...
switch 같은 경우에는 case의 인덱스를 이쁘게 잘 짜 놓으신다면
switch문에서 jump table을 만들어 버리고 offset + jumptable의 인덱스만큼 점프를 한 값으로 바로 확 뛰어 버린답니다.
그러니까 엄청난 분기문을 타던 케이스를 한 번의 연산으로 처리를 해버리는 거죠
이런 코드가 있다면 어셈블리는 다음과 같이 뽑힐 것이고 메모 리뷰도 함께 보겠습니다.
1번째 실험케이스1번째 실험 케이스2번째 실험 케이스
자 보이시나요..?
메모리에 예쁘게 그려진 무언가가 보이죠..?
혹시 모르실까 봐 싶어서 어셈블리 옆에 코드 주소까지 달려있게 해 놨는데...
케이스를 1~60까지 넣었더니 jump 할 곳들을 담는 메모리를 가지고 있고
00~ 09와 0a가 포함된 1바이트의 배열 60칸이 생겼습니다.
그 밑에 어떤 값이 나오면 오프셋에 이 값을 더해서 바로 점프하라는 메모리 배열들이 있습니다.
이 값은 스위치 문에 있는 값 중 가장 작은 값을 0번으로 생각하고 그 뒤로부터 값이 매겨지는 식으로 증가합니다.
offset + jump tbl의 [0] 값을 더한 곳으로 점프하라라고 하는 것입니다...
반대로 저 스위치 문에 없는 2를 넣게 되면 0a라는 값이 나오게 되는데
총 스위치 문의 개수는 10개 인덱스로 따지면 9죠 그래서 10을 넣게 되면 스위치 문을 빠져나가는 주소로 점프를 해버린답니다... 저런 식으로 만들어져 있어요 그렇다면 여기서 한 가지 짚고 넘어가야 될 점
안 되는 케이스도 분명히 있을 겁니다. 만약 인덱스가 255가 넘어버린다면 1바이트 안에 담을 수가 없으므로 점프 테이블 인덱스가 의미가 없어질 겁니다. 그래서 인덱스가 255개를 넘지 않으면서 동시에 255 이상의 값이 없으면서 가지런히 놓여 있다면 switch문이 더 효율적일 것입니다. enum을 쓰실 때 개수가 255개 이하라고 한다면 if else 분기를 타는 것보다 훨씬 더 효율적이다 라는 결과를 도출해낼 수 있겠습니다.
그래서 상황에 맞게 switch문을 잘 쓰시면 if else문 보다 빠르지만 위에서 말씀드렸던 그 조건에 부합하지 않는다면 switch문도 결국 cmp jmp cmp jmp를 반복하면서 if else if~~... else 문과 동일한 결과를 나타내게 되므로 결론은
스위치 문을 이쁘게 잘 짜자입니다.. ㅎㅎ
오늘은 여기까지 하도록 하겠습니다. 유익한 정보가 되었으면 좋겠습니다. 이번에도 긴 글 읽어주셔서 정말 감사드립니다. 저는 다음 내용을 준비해서 또 오도록 하겠습니다 그럼 안녕히 계세요!!