2014-08-24 4 views
5
if(a() && b() && c() && d()) 
    doSomething(); 


if(a()) 
    if(b()) 
     if(c()) 
     if(d()) 
      doSomething(); 

Есть ли какая-либо разница в производительности между этими двумя?Вложенные операторы if и оператор «&&»

Например, в ситуации, когда a() поворачивает 0, будет ли он продолжать работать с b(), c() и d() в первом случае if? Или он будет работать так же, как второй вложенный оператор if?

+3

[ Оценка короткого замыкания] (http://en.wikipedia.org/wiki/Short-circuit_evaluation) – chris

+0

Это не вызов b(), c(), d(), если a() оценивается как false. && является оператором короткого замыкания –

+0

@UchiaItachi, он также замыкается на замыкание с 'if'. –

ответ

9

Они точно идентичны.

Чтобы проверить это самостоятельно, запустите gcc -S test.c (предположим, что именно здесь вы разместили свой источник) и наблюдайте за содержимым test.s.


Вот как nested- if подход компилирует в GCC 4.8.1 с параметрами по умолчанию (аннотированный с комментариями):

main: 
.LFB0: 
    .cfi_startproc 
    pushq %rbp 
    .cfi_def_cfa_offset 16 
    .cfi_offset 6, -16 
    movq %rsp, %rbp 
    .cfi_def_cfa_register 6 
    movl $0, %eax 
    call A      # try to call A 
    testl %eax, %eax    # look at its return value 
    je .L3       # short-circuit if it returned 0 
    movl $0, %eax     # ...repeat for B, et al. 
    call B 
    testl %eax, %eax 
    je .L3 
    movl $0, %eax 
    call C 
    testl %eax, %eax 
    je .L3 
    movl $0, %eax 
    call D 
    testl %eax, %eax 
    je .L3 
    movl $0, %eax 
    call doSomething 
.L3: 
    popq %rbp 
    .cfi_def_cfa 7, 8 
    ret 
    .cfi_endproc 

Вот как && подход компилирует:

main: 
.LFB0: 
    .cfi_startproc 
    pushq %rbp 
    .cfi_def_cfa_offset 16 
    .cfi_offset 6, -16 
    movq %rsp, %rbp 
    .cfi_def_cfa_register 6 
    movl $0, %eax 
    call A       # try to call A 
    testl %eax, %eax     # look at its return value 
    je .L3        # short-circuit if it returned 0 
    movl $0, %eax     # ...repeat for B, et al. 
    call B 
    testl %eax, %eax 
    je .L3 
    movl $0, %eax 
    call C 
    testl %eax, %eax 
    je .L3 
    movl $0, %eax 
    call D 
    testl %eax, %eax 
    je .L3 
    movl $0, %eax 
    call doSomething 
.L3: 
    popq %rbp 
    .cfi_def_cfa 7, 8 
    ret 
    .cfi_endproc 
+0

Я бы дважды отвел этот ответ, если бы мог – NonSecwitter

Смежные вопросы