Для удобства чтения я люблю писать булевы условия «полностью» на C / C ++, например:
if (foo == true)
вместо if (foo)
а также if (foo == false)
вместо if (!foo)
,
Влияет ли это на производительность?
Что касается прямой С, две формы может привести к другому машинному коду, который может влияет на производительность. То ли разница в производительности вопросы будет зависеть от того, что делает код и каковы ваши требования к производительности.
Используя gcc 4.1.2 на SLES 10, я получаю немного другой машинный код для if ( foo == false )
против if ( !foo )
; учитывая следующий исходный код:
if ( foo == false )
{
printf( "foo is false\n" );
}
if ( !foo )
{
printf( "foo is 0\n" );
}
Я получаю следующий машинный код (gcc -S -std=c99 -pedantic -Wall -Werror
):
movb $0, -1(%rbp) ;; foo = false
cmpb $0, -1(%rbp) ;; if ( foo == false )
jne .L6 ;; {
movl $.LC2, %edi ;;
call puts ;; printf( "foo is false\n" );
.L6: ;; }
movzbl -1(%rbp), %eax ;; if ( !foo )
xorl $1, %eax
testb %al, %al
je .L8 ;; {
movl $.LC3, %edi ;;
call puts ;; printf( "foo is 0\n" );
.L8: ;; }
movl $0, %eax
Для этой конкретной платформы, компилятора, кода и набора опций компилятора, if (!foo)
может оказаться немного медленнее, чем if ( foo == false )
1.
Теперь, для реального вопроса: имеет ли значение эта разница в производительности (если она существует)? Для этой конкретной программы абсолютно нет; тест проводится один раз за время существования программы, и время, затрачиваемое на выполнение операций ввода-вывода, будет значительно больше времени, потраченного на выполнение теста. В другой программе, где этот тест выполняется тысячи или миллионы раз в узком цикле, связанном с процессором, тогда это может иметь большое значение.
Код для читабельности первый; if ( foo )
а также if ( !foo )
формы, как правило, идиоматичны для простых булевых тестов, и именно этого ожидают увидеть большинство программистов на C и C ++. Сказав это, здесь нет ничего плохого в написании if ( foo == TRUE )
а также if ( foo == FALSE )
если вы чувствуете, что он лучше передает смысл кода (или если вы решили определить TRUE
как 0 и FALSE
как 1 по любой причине).
Но не принять это решение на основе производительности если:
1. Или нет; это зависит от того, сколько циклов xorl
а также testb
требовать против cmpb
и насколько быстрее это зарегистрироваться %eax
непосредственно, чем вычислять -1(%rbp)
и получить доступ к полученному местоположению; Насколько я знаю, это мытье.
Предполагая, что foo это бул, это не так. Это может быть тривиально оптимизировано компилятором.
Однако это может быть не так, если foo является классом, который может перегружать операторы, чтобы они делали что угодно.
if(foo == true)
Даже при злых перегрузках он может иметь другую семантику и характеристики производительности, чем более идиоматический, потому что он менее многословный
if( ! foo)
, с разумными типами и достаточно эффективными компиляторами, он должен производить точно такие же нативные инструкции.
Если вы допустите злонамеренную перегрузку, все ставки в любом случае будут отменены, и вы получите ту проблему, которую ожидаете.
Тем не менее, вышеупомянутое не является каноническим примером для глупости всегда добавлять явное сравнение.
Это было бы:
if(foo)
if(foo == true)
if((foo == true) == true)
// ...
Недостатки:
=
и так, пытаясь присвоить значение.Имейте в виду, что в C, C ++ и некоторых родственных языках то же самое относится и к указателям, целым числам (включая символьные типы) и большинству пользовательских типов.
Предполагая, что foo это бул, это не так. Это может быть тривиально оптимизировано компилятором.
Однако это может быть не так, если foo является классом, который может перегружать операторы, чтобы они делали что угодно.