В C ++ оператор?: Работает быстрее, чем операторы if () ... else? Есть ли между ними различия в скомпилированном коде?
if
позволяет операторы.
В C ++ оператор?: Работает быстрее, чем операторы if () ... else? Есть ли между ними различия в скомпилированном коде?
if
позволяет операторы.
Ответы:
Зависит от вашего компилятора, но на любом современном компиляторе обычно нет разницы. Об этом не стоит беспокоиться. Сконцентрируйтесь на ремонтопригодности вашего кода.
Это не быстрее. Есть одно отличие, когда вы можете инициализировать постоянную переменную в зависимости от некоторого выражения:
const int x = (a<b) ? b : a;
Вы не можете сделать то же самое с if-else
.
const
переменной.
max
? const int x = max(a,b);
работает нормально.
max ? const int x = max(a,b);
и подумал: «Эй! Что это за хрень! затем я прочитал его еще раз и заметил, что вопросительный знак не моноширинный! учитывая тему, я думаю, что я был прав, думая о? был частью команды! :)
const int x = [&] -> int { if (a < b) return b; else return a; }
.
Я видел, как GCC превращал условный оператор в cmov
инструкции (условного перемещения), одновременно превращая if
операторы в ветки, что означало, что в нашем случае код был быстрее при использовании условного оператора. Но это было пару лет назад, и, скорее всего, сегодня оба компилируются в один и тот же код.
Нет гарантии, что они будут компилироваться в один и тот же код. Если нужна производительность то, как всегда, измерьте . И когда вы измерили и обнаружили, что 1. ваш код слишком медленный, и 2. именно этот фрагмент кода является виновником, изучите ассемблерный код, сгенерированный компилятором, и проверьте сами, что происходит.
Не верьте золотым правилам вроде «компилятор всегда будет генерировать более эффективный код, если я использую условный оператор».
Only one of the second and third expressions is evaluated. Every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second or third expression.
что, по-видимому, не позволяет компилятору генерировать cmove
инструкции.
Они одинаковы, однако тернарный оператор можно использовать в тех местах, где сложно использовать if / else:
printf("Total: %d item%s", cnt, cnt != 1 ? "s" : "");
Выполнение этого оператора с if / else приведет к созданию совершенно другого скомпилированного кода.
Обновление через 8 лет ...
На самом деле, я думаю, было бы лучше:
printf(cnt == 1 ? "Total: %d item" : "Total: %d items", cnt);
(на самом деле, я почти уверен, что вы можете заменить "% d" в первой строке на "один")
printf("Total: %d item%s", cnt, "s" + (cnt==1));
lpStrFilter
составе OPENFILENAME структур )
%s
печатает до, но не включая \0
исходную строку.
printf("Total: %d item%s", cnt, "s" + (cnt==1));
работает?
(cnt==1)
истинно или ложно, что преобразуется в 0 или 1. «s» - указатель на строку с завершающим нулем. Добавление одного пропускает один символ (s). Таким образом, это печатает либо «s», либо «».
Просто чтобы быть немного левшой ...
x ? y : x = value
присвоит значение , чтобы у , если х не равен 0 (ложь).
Независимо от скомпилированного кода, они семантически разные. <cond>?<true expr>:<false expr>
является выражением и if..else..
является утверждением.
Хотя синтаксис условного выражения кажется неудобным, это хорошо. Вы вынуждены указать, <false expr>
и два выражения проверяются по типу.
Эквивалент if..else..
основанного на выражениях функционального языка, такого как Lisp, Haskell находится ? :
на C ++, а не на if..else..
операторе.
Я ожидал, что на большинстве компиляторов и целевых платформ будут случаи, когда «если» быстрее, а случаи, когда?: Быстрее. Также будут случаи, когда одна форма более или менее компактна, чем другая. В каких случаях предпочтительна та или иная форма, зависит от компилятора и платформы. Если вы пишете критически важный для производительности код на встроенном микроконтроллере, посмотрите, что компилятор генерирует в каждом случае, и выберите, что лучше. На «массовом» ПК из-за проблем с кешированием единственный способ увидеть, что лучше, - это протестировать обе формы в чем-то похожем на реальное приложение.
В CA тернарный оператор "?:" Доступен для построения условных выражений вида
exp1 ? exp2:exp3
где exp1, exp2 и exp3 - выражения
например
a=20;
b=25;
x=(a>b)?a:b;
in the above example x value will be assigned to b;
Это можно записать с помощью оператора if..else следующим образом
if (a>b)
x=a;
else
x=b;
** Следовательно, между этими двумя нет разницы. Программисту это будет легко написать, но для компилятора они одинаковы. *
Во время реверсирования некоторого кода (который я не помню, несколько лет назад) я увидел разницу в одну строку между машинным кодом:? а если-еще.
Don't remember much but it is clear that implementation of both is different.
Но советую не выбирать один из них из-за его эффективности, выбирать по удобочитаемости кода или удобству. Счастливое кодирование
Тернарный оператор всегда возвращает значение. Поэтому в ситуации, когда вы хотите получить какое-то выходное значение из результата и есть только 2 условия, всегда лучше использовать тернарный оператор. Используйте if-else, если любое из вышеупомянутых условий не выполняется.
Я думаю, что бывают ситуации, когда встроенный if может давать «более быстрый» код из-за области, в которой он работает. Создание и уничтожение объектов может быть дорогостоящим, поэтому рассмотрите следующий сценарий:
class A{
public:
A() : value(0) {
cout << "Default ctor" << endl;
}
A(int myInt) : value(myInt)
{
cout << "Overloaded ctor" << endl;
}
A& operator=(const A& other){
cout << "= operator" << endl;
value = other.value;
}
~A(){
cout << "destroyed" << std::endl;
}
int value;
};
int main()
{
{
A a;
if(true){
a = A(5);
}else{
a = A(10);
}
}
cout << "Next test" << endl;
{
A b = true? A(5) : A(10);
}
return 0;
}
С этим кодом вывод будет:
Default ctor
Overloaded ctor
= operator
destroyed
destroyed
Next test
Overloaded ctor
destroyed
Таким образом, вставляя if, мы сохраняем кучу операций, необходимых для сохранения a
активности в той же области, что и b
. Хотя весьма вероятно, что скорость оценки условий в обоих сценариях примерно одинакова, изменение области действия заставляет вас принимать во внимание другие факторы, которых позволяет избежать встроенный if.
A a(true ? 5 : 10);
Теперь я не могу вам с этим помочь, возможно, я смогу помочь с второстепенным вопросом под ним, хочу ли я его использовать? Если вы просто хотите узнать о скорости, просто проигнорируйте мой комментарий.
Все, что я могу сказать, - пожалуйста, будьте очень умны, когда использовать троичный? : оператор. Это может быть как благословением, так и проклятием для удобочитаемости.
Спросите себя, легче ли вам это прочитать, прежде чем использовать
int x = x == 1 ? x = 1 : x = 1;
if (x == 1)
{
x = 1
}
else
{
x = 2
}
if (x == 1)
x = 1
else
x = 1
Да. Совершенно глупо делать код на 100% поддельным. Но эта маленькая уловка помогла мне проанализировать читаемость кода. В этом примере вы смотрите на удобочитаемость оператора, а не на его содержимое.
Выглядит чистым, как и обычное сиденье унитаза и дверная ручка.
По моему ограниченному опыту, я видел очень мало людей, действительно способных быстро выдать информацию, требуемую от тернарного оператора, избегая, если не уверен на 100%, что это лучше. Это больно исправлять, когда он тоже прослушивается, я думаю
int x = x == 1 ? 1 : 2
или, возможно,int x = (x == 1) ? 1 : 2
x = x = 1;
везде, а потом пожаловаться, что задание слишком сложное и его следует избегать.