"iff" 대 "if other if"의 성능 차이
C/C++의 두 문장 사이에 성능 차이가 있는지 생각하고 있었습니다.
사례 1:
if (p==0)
do_this();
else if (p==1)
do_that();
else if (p==2)
do_these():
사례 2:
if(p==0)
do_this();
if(p==1)
do_that();
if(p==2)
do_these();
단순한 유형을 가정할 때(이 경우 사용했습니다.int
) 및 재미있는 비즈니스는 없습니다(operator= forint를 재정의하지 않음). 적어도 AMD64의 GCC 4.6에서는 차이가 없습니다.생성된 코드는 동일합니다.
0000000000000000 <case_1>: 0000000000000040 <case_2>:
0: 85 ff test %edi,%edi 40: 85 ff test %edi,%edi
2: 74 14 je 18 <case_1+0x18> 42: 74 14 je 58 <case_2+0x18>
4: 83 ff 01 cmp $0x1,%edi 44: 83 ff 01 cmp $0x1,%edi
7: 74 27 je 30 <case_1+0x30> 47: 74 27 je 70 <case_2+0x30>
9: 83 ff 02 cmp $0x2,%edi 49: 83 ff 02 cmp $0x2,%edi
c: 74 12 je 20 <case_1+0x20> 4c: 74 12 je 60 <case_2+0x20>
e: 66 90 xchg %ax,%ax 4e: 66 90 xchg %ax,%ax
10: f3 c3 repz retq 50: f3 c3 repz retq
12: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 52: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
18: 31 c0 xor %eax,%eax 58: 31 c0 xor %eax,%eax
1a: e9 00 00 00 00 jmpq 1f <case_1+0x1f> 5a: e9 00 00 00 00 jmpq 5f <case_2+0x1f>
1f: 90 nop 5f: 90 nop
20: 31 c0 xor %eax,%eax 60: 31 c0 xor %eax,%eax
22: e9 00 00 00 00 jmpq 27 <case_1+0x27> 62: e9 00 00 00 00 jmpq 67 <case_2+0x27>
27: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 67: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
2e: 00 00 6e: 00 00
30: 31 c0 xor %eax,%eax 70: 31 c0 xor %eax,%eax
32: e9 00 00 00 00 jmpq 37 <case_1+0x37> 72: e9 00 00 00 00 jmpq 77 <case_2+0x37>
37: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
3e: 00 00
case_1의 끝에 있는 추가 명령어는 (다음 함수를 정렬하기 위해) 패딩을 위한 것입니다.
이 함수에서 p가 변하지 않는다는 것을 파악하는 것은 상당히 기본적인 최적화입니다.p를 변경할 수 있는 경우(예: pass-by-reference 또는 pointer to various)do_…
함수, 또는 참조 또는 포인터 자체였으므로 별칭이 있을 수 있습니다). 그러면 동작이 다르며, 물론 생성된 코드도 마찬가지입니다.
전자의 경우 일치된 조건 이후의 조건은 평가되지 않습니다.
다른 경우에는 더 빠릅니다. 일치하는 항목이 마지막에 발견된 경우에는 최소한 마지막에 발견된 경우에는 문을 건너뛰고, 일치하는 경우에는 일치하는 항목이 처음에 발견된 경우에는 다른 모든 문을 건너뜁니다.
if가 더 느릴 경우, first if 문을 사용하여 일치가 발견되더라도 다른 문에서 일치를 계속 시도합니다.
예, 성능 차이는 다음과 같습니다.
두 번째 문장은 모든 IF를 평가합니다.
이미 입증되었듯이...다양합니다.
만약 우리가 원시적인 (빌트인) 유형에 대해 이야기한다면 다음과 같습니다.int
, 그러면 컴파일러는 문제가 되지 않을 정도로 충분히 똑똑할 수 있습니다.그러나 어떤 경우에도, 함수를 호출하는 비용이 a보다 훨씬 높기 때문에 성능에 미치는 영향은 미미할 것입니다.if
, 측정을 시도하면 소음 속에서 차이가 날 수 있습니다.
그러나 의미론은 상당히 다릅니다.
첫 번째 사례를 읽었을 때:
if (...) {
// Branch 1
} else if (...) {
// Branch 2
}
그렇다면 두 갈래가 어떻게 하든 한 갈래만 실행할 수 있다는 것을 알고 있습니다.
하지만 두번째 케이스를 읽었을때는
if (...) {
}
if (...) {
}
그러면 두 갈래 모두 취해질 가능성이 있는지, 그렇지 않은지, 두 번째 시험에 영향을 미칠 가능성이 있는지를 판단하기 위해 첫 번째에 코드를 꼼꼼히 살펴봐야 한다는 의미입니다.그리고 내가 마침내 아니라고 결론을 내렸을 때, 나는 그 망할 놈의 글을 쓰기엔 너무 게을렀던 빌어먹을 개발자를 저주합니다.else
지난 10분간의 정밀 조사 시간을 아낄 수 있었을 겁니다
그러니 자신과 미래의 유지 관리자들을 돕고, 의미론을 정확하고 명확하게 하는 데 집중하세요.
이, 이 에 은 가 과 될 할 할 될 은 switch
도a.map<int, void()>
을 피함 고잉를함e;)함를( ; )
이처럼 제한된 수의 표현에 대한 성능 차이는 아마 발견되지 않을 것입니다.으로는.if..if..if
모든 식을 확인해야 합니다.배타적인 일이우을여를할수다호인수다gynlfesuse,tny호ee인를if..else if..
◦ 을 확인할수 .앞의 사례가 실패했을 때만 다른 식을 확인할 수 있습니다.
는 을 int 를 할 은 할 할 을 은 switch
◦ 하면 긴할 수 .이렇게 하면 긴 검사 순서 동안에도 가독성을 어느 정도 유지할 수 있습니다.
switch ( p )
{
case 0:
do_this();
break;
case 1:
do_that();
break;
case 2:
do_these():
break;
}
if..실제 논리는 좌-우로 평가되므로 이후의 모든 IF 검사에서 DONE 플래그를 사용하여 이중 작업/일치 및 최적화를 방지함으로써 사례를 개선할 수 있는 경우.
bool bDone = false;
If( <condition> ) {
<work>;
bDone = true;
}
if (!bDone && <condition> ) {
<work>;
bDone = true;
}
아니면 다음과 같은 논리를 사용할 수도 있습니다.
While(true) {
if( <condition> ) {
<work>;
break;
}
if( <condition> ) {
<work>;
break;
}
....
break;
}
읽기에는 다소 혼란스럽지만 ("왜 이런 식으로"라고 묻습니다)
주요 차이점은 if/else 구성이 if() 중 하나가 참을 반환하면 평가를 중지한다는 것입니다.즉, 보석하기 전에 if 중 1개 또는 2개만 실행할 수 있습니다.다른 버전은 다른 버전의 결과에 관계없이 3가지의 모든 if를 확인합니다.
그럼.. 만약.. "최대 3번의 점검"의 운영 비용이 있다면요.if/if/if 버전의 운영 비용은 "항상 3개 확인"입니다.검사 중인 3개의 값이 모두 동일한 가능성이 있다고 가정하면 if/else 버전은 평균 1.5개의 if를 수행하는 반면 if/if 버전은 항상 3개의 if를 수행합니다.장기적으로는 "다른" 컨스트럭트를 사용하면 1.5 ifs의 CPU 시간을 절약할 수 있습니다.
언급URL : https://stackoverflow.com/questions/7970275/performance-difference-of-if-if-vs-if-else-if
'programing' 카테고리의 다른 글
getopt_long() -- 적절한 사용 방법은 무엇입니까? (0) | 2023.09.15 |
---|---|
특정 RUN 명령에 대해 캐시 사용 안 함 (0) | 2023.09.15 |
React Native에서 Android의 패키지 이름 변경 (0) | 2023.09.15 |
SQL에서 DateTime 필드의 시간 부분 (0) | 2023.09.15 |
이 Oracle 쿼리를 MariaDB로 올바르게 변환하는 방법은 무엇입니까? (0) | 2023.09.10 |