for (int i = 0; i < 20; i++) { }
for (int i = 0; i < 20; ++i) { }
++i
이 i++
보다 빠르다” C++하는 사람들은 한 번 쯤은 들어봤을법한 말이죠.++i
가 i++
보다 빠른지 점검 해보신 적 있으신가요?++i
가 i++
보다 빠른지 이유는 알고 계신가요? for (int i = 0; i < 20; i++) { }
003050D2 mov dword ptr [ebp-0Ch],0
003050D9 jmp __$EncStackInitStart+38h (03050E4h)
003050DB mov eax,dword ptr [ebp-0Ch]
003050DE add eax,1
003050E1 mov dword ptr [ebp-0Ch],eax
003050E4 cmp dword ptr [ebp-0Ch],14h
003050E8 jge __$EncStackInitStart+40h (03050ECh)
003050EA jmp __$EncStackInitStart+2Fh (03050DBh)
for (int i = 0; i < 20; ++i) { }
003050EC mov dword ptr [ebp-18h],0
003050F3 jmp __$EncStackInitStart+52h (03050FEh)
003050F5 mov eax,dword ptr [ebp-18h]
003050F8 add eax,1
003050FB mov dword ptr [ebp-18h],eax
003050FE cmp dword ptr [ebp-18h],14h
00305102 jge __$EncStackInitStart+5Ah (0305106h)
00305104 jmp __$EncStackInitStart+49h (03050F5h)
(VisualStudio 2019, C++ 14, Debug, x86 기준입니다)
++i
와 i++
에 해당하는 어셈블리 코드의 양이 “동일하다”는 것만 척 보면 알게됩니다.++i
나 i++
이나 성능상으로 “동일하다”는 뜻입니다.++i
가 i++
보다 빠르다고들 말하는 걸까요? 그 이유는 연산자 오버로딩에 있습니다.struct CounterStruct {
int a;
CounterStruct() : a(0) {}
CounterStruct& operator++() { a = a + 1; return *this; } // ++CounterStruct 연산
CounterStruct operator++(int) { a = a + 1; return *this; } // CounterStruct++ 연산
};
for (CounterStruct cs; cs.a < 20; cs++) { }
for (CounterStruct cs; cs.a < 20; ++cs) { }
for (CounterStruct cs; cs.a < 20; cs++) { }
00895103 lea ecx,[ebp-24h]
00895106 call CounterStruct::CounterStruct (08913A7h)
0089510B jmp __$EncStackInitStart+72h (089511Eh)
0089510D push 0 ; 추가된 코드
0089510F lea eax,[ebp-120h] ; 추가된 코드
00895115 push eax ; 추가된 코드
00895116 lea ecx,[ebp-24h]
00895119 call CounterStruct::operator++ (08913B1h)
0089511E cmp dword ptr [ebp-24h],14h
00895122 jge __$EncStackInitStart+7Ah (0895126h)
00895124 jmp __$EncStackInitStart+61h (089510Dh)
for (CounterStruct cs; cs.a < 20; ++cs) { }
00895126 lea ecx,[ebp-30h]
00895129 call CounterStruct::CounterStruct (08913A7h)
0089512E jmp __$EncStackInitStart+8Ch (0895138h)
00895130 lea ecx,[ebp-30h]
00895133 call CounterStruct::operator++ (089139Dh)
00895138 cmp dword ptr [ebp-30h],14h
0089513C jge __$EncStackInitStart+94h (0895140h)
0089513E jmp __$EncStackInitStart+84h (0895130h)
cs++
코드가 ++cs
코드보다 더 깁니다! 드디어 ++cs
가 이겼군요! 그런데 이런일이 왜 일어날까요?CounterStruct& operator++() { a = a + 1; return *this; } // ++CounterStruct 연산
CounterStruct operator++(int) { a = a + 1; return *this; } // CounterStruct++ 연산
++CounterStruct
연산자는 레퍼런스를 리턴하고 CounterStruct++
연산자는 밸류를 리턴하도록 되어있죠?CounterStruct++
함수는 실제 리턴된 밸류값을 사용하지 않더라도 “밸류”를 리턴해야 하는 함수이기에 이를 위한 비용이 추가적으로 들어가야 하는게(원론적으론) 의무입니다.++CounterStruct
연산자가 CounterStruct++
연산자보다 빠른 것이죠.++i
와 i++
의 성능차이가 존재하지 않는다.++cs
와 cs++
의 성능차이가 존재한다. ++cs
를 쓰는 것이 맞습니다.++i
가 i++
보다 빠르다고 너무 쉽게 단언하지 않았는지 생각해 봅시다.#include <cstdio>
struct CounterStruct {
int a;
CounterStruct() : a(0) {}
CounterStruct& operator++() { a = a + 1; return *this; } // ++CounterStruct 연산
CounterStruct operator++(int) { a = a + 1; return *this; } // CounterStruct++ 연산
};
int main(void) {
for (int i = 0; i < 20; i++) { }
for (int i = 0; i < 20; ++i) { }
for (CounterStruct cs; cs.a < 20; cs++) { }
for (CounterStruct cs; cs.a < 20; ++cs) { }
return 0;
}