2014-09-23 3 views
-1

Скажем, у нас есть объект, и что нам нужно проверить следующие вещи -Какой оператор if будет выполняться быстрее?

  • Объект-> длина текста больше, чем 0
  • Объект-> манекен не является нулевым
  • Objecct-> dummy2 существует в другом объекте

у нас есть две возможности для если заявление:

if(greaterThan(Object->text, 0) && 
    exists(Objet->dummy) && 
    inObject(Object->dummy2, Objet2)) 

Во-вторых, если:

if(!greaterThan(Object->text, 0) || 
     !exists(Objet->dummy) || 
     !inObject(Object->dummy2, Objet2)) { 
    NOP 
} else { 
    //Do something; 
} 

Какой будет быстрее? Заранее спасибо.

+2

Зачем вам все это? Вы заметили, что в нем есть хиты производительности? Я действительно сомневаюсь. «Преждевременная оптимизация - это корень всего зла» ... Просто напишите, что легче всего читать. –

+0

generalu first one, так как у вас меньше операций, худший случай первого - 2, а в худшем случае второй - 2 ИЛИ и 3 НЕЗАВРАЩЕНИЕ – user902383

+1

Почему вас это волнует, почему он заботится? Просто повторяя усталую «преждевременную оптимизацию ...», вы указываете, что вы подразумеваете, что OP фактически оптимизирует это преждевременно и даже что он оптимизирует все это. Иногда вы просто хотите знать _why_, даже если нет практической выгоды. Действительно, вопрос помечен темой «Теория» ... – BeeOnRope

ответ

2

В общем, эти две формы эквивалентны, и достойный компилятор, вероятно, скомпилирует их на ту же конечную сборку. Конечно, вы должны проверить свой конкретный компилятор. Вы можете посмотреть на выходе сборки нескольких компиляторов здесь для вашей проблемы:

http://goo.gl/FeSmEa

Например, НКУ 4,9 выхода:

void function1() { 
    if (greaterThan() && exists() && inObject()) { 
    result = 42; 
    } 
} 

дает:

function1(): 
    sub rsp, 8 
    call greaterThan() 
    test eax, eax 
    jne .L13 
.L1: 
    add rsp, 8 
    ret 
.L13: 
    call exists() 
    test eax, eax 
    je .L1 
    call inObject() 
    test eax, eax 
    je .L1 
    mov DWORD PTR result[rip], 42 
    jmp .L1 

, а другой вариант:

void function2() { 
    if (!greaterThan() || !exists() || !inObject()) { 
    // NOP 
    } else { 
    result = 42; 
    } 
} 

приводит к идентичной сборки:

function2(): 
    sub rsp, 8 
    call greaterThan() 
    test eax, eax 
    jne .L28 
.L14: 
    add rsp, 8 
    ret 
.L28: 
    call exists() 
    test eax, eax 
    je .L14 
    call inObject() 
    test eax, eax 
    je .L14 
    mov DWORD PTR result[rip], 42 
    jmp .L14 

Во всех случаях составители получают одинаковую сборку для обоих вариантов (я упростил его немного, удалив некоторые аргументы, но это должно быть несущественно).

+0

Да, я полностью ожидаю, что все разумные компиляторы будут скомпилировать их одинаково. – biziclop

+0

ой, это интересно. Я спрашивал, потому что я хотел предотвратить, если бы от вызова других функций, спасибо – Yehonatan

+0

Вам не нужно смотреть на сборку, чтобы определить, что: язык определяет булевские операторы, и поэтому по определению вы не будете звонить функции, когда значение булевского выражения уже установлено. Что касается этого поведения, ваши два выражения эквивалентны. В этом случае важно, чтобы вы вставляли свои выражения. Вам нужен тот, который с большей вероятностью «коротко замыкает» остальную часть выражения. Например, для 'A && B' вы хотите указать, какой из« A »или« B », скорее всего, будет ложным, в первую очередь. – BeeOnRope

-2

Использование логического И (&) будет более быстрым. Причина этого в том, что вам нужны все 3 условия, которые должны быть удовлетворены, И проигнорировал бы проверку остальной части условий, даже если один из них не прошел. ИЛИ проверит все 3 безответственные из которых из условий не работают.

+0

с тем, что, однако, оба утверждения if не эквивалентны. Пожалуйста, проверьте это, если вы используете его как часть своего кода –

+2

, в каком виде они не эквивалентны? 'A && B && C ==! (! A ||! B ||! C)'. Обратите внимание, что он поставил свой код в другом во втором случае, эффективно получив внешний!. – BeeOnRope

+1

Этот ответ неверен, я боюсь. В языках, где '&&' закорачивается, '||' также закорачивается. Таким образом, они будут эквивалентны. Если 'moreThan (...) 'возвращает' false', его отрицание вернет 'true', поэтому оценка оператора' || 'остановится. – biziclop

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