2016-03-31 4 views
0

Что было бы более эффективным?Эффективно ли проверить нуль?

if(foo != 0) 
{ 
    bar += foo; 
} 

или

bar += foo; 

Предполагая, что Foo может иметь приличный шанс быть 0 (скажем, 25%, но может сделать другие предположения о процентах, очевидно, 0% будет означать, что последний всегда более эффективно)

Есть ли консенсус о том, когда вы должны использовать один над другим, или люди делают такие вещи, как профилирование, для определения фактического более эффективного выражения?

+15

Такие микрооптимизации следует избегать до тех пор, пока вы не профилируете и не обнаружите, что есть проблема с кодом. Код для удобочитаемости и ремонтопригодности и только после того, как вы знаете, что вам нужно. – NathanOliver

+0

Можно ли считать, что оператор '+ =' является встроенным, и он не перегружен? – anatolyg

+0

@ anatolyg, как это важно, поскольку оба используют один и тот же оператор? – uSeemSurprised

ответ

2

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

Например, если вы пишете:

const foo == 0; 
if(foo != 0) 
{ 
bar += foo; 
} 

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

Что касается проверки на 0, если существует большая вероятность, что значение равно 0, то имеется эвристика процессора на месте (называемая предсказанием ветвления), которая автоматически проверяет возможность пролонгации, сколько раз в прошлом выполнялось утверждение if (когда оно находится в while/for loop) и «предсказывает» результат утверждения.

Это question показывает разницу, которая может иметь разветвление при выполнении кода очень хорошо.

+1

Это очень глупый оператор if, поскольку вы знаете, что переменные 'const' не изменяются. – NathanOliver

+0

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

+1

Я считаю, что разница не может быть измерена на уровне C++. По крайней мере, нужно взглянуть на скомпилированный ассемблерный код. – WhatsUp

-1

Это оптимизация не требуется. assembly

if(foo != 0) переводит в инструкции на две сборки

и bar += foo; транслируется в два также

Так что я бы сказал, если мы также добавить небольшое разветвление сделано, если заявление, я думаю, что лучше просто добавьте foo в bar, даже если много раз не влияет на значение бара.

+0

Вы не скомпилировались с оптимизацией, просмотр сборки для производительности бессмыслен. – GManNickG

-1

Конечно, проверка более эффективна. Предположим, что 25% шанс быть 0, поэтому в 100 раз, вызывая с полной вероятностью, вы пропустите, чтобы скомпилировать эту строку 25 раз. Таким образом, в лучшем случае ваша сложность составляет менее 25%.

+1

проверка стоимости инструкции (-ов), так ли это действительно более эффективно? – NathanOliver

+0

Является ли проверка еще более эффективной, если она вызывает неверное предсказание ветки, а затем флеш-конвейер? Что делать, если команды сравнения и перехода приводят к тому, что критический фрагмент кода будет немного длиннее кэша команд, что приведет к промаху кеша на каждой итерации через код? Единственный способ сказать наверняка - измерить фактическую производительность кода или проанализировать сгенерированную сборку с очень прочной ментальной моделью процессора, на которой он будет выполнен. – joelw

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