Тернарный оператор: vs if ... else
В C++ есть ?: оператор быстрее, чем если()...еще заявления? Есть ли различия между ними в скомпилированном коде?
14 ответов:
зависит от вашего компилятора, но на любом современном компиляторе, как правило, нет никакой разницы. Это то, о чем тебе не стоит беспокоиться. Сосредоточьтесь на ремонтопригодности вашего кода.
это не быстрее. Есть одно отличие, когда вы можете инициализировать постоянную переменную в зависимости от некоторого выражения:
const int x = (a<b) ? b : a;
вы не можете сделать то же самое с
if-else
.
Я видел, как GCC превращает условный оператор в
cmov
(условное перемещение) инструкции, при поворотеif
операторы в ветвях, что означало в нашем случае, что код был быстрее при использовании условного оператора. Но это было пару лет назад, и, скорее всего, сегодня, оба будут компилироваться в один и тот же код.нет никакой гарантии, что они компилируются в один и тот же код. Если вам нужна производительность, то, как всегда, мера. И когда ты измерили и выяснили, что 1. ваш код слишком медленный, и 2. именно этот конкретный кусок кода является виновником, а затем изучите ассемблерный код, сгенерированный компилятором, и проверьте для себя, что происходит.
Не доверяйте золотым правилам, таким как"компилятор всегда будет генерировать более эффективный код, если я использую условный оператор".
они одинаковы, однако тернарный оператор может использоваться в тех местах, где трудно использовать 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" в первой строке на "один")
независимо от скомпилированного кода, они семантически разные вещи.
<cond>?<true expr>:<false expr>
- Это выражение иif..else..
это заявление.хотя синтаксис условного выражения кажется неудобным, это хорошая вещь. Вы вынуждены предоставить
<false expr>
и эти два выражения проверяются по типу.эквивалентно
if..else..
в функциональном языке на основе выражений, таком как Lisp, Haskell is? :
в C++, вместоif..else..
заявление.
теперь я не могу помочь вам с этим, я могу помочь с вторичным вопросом под ним, хочу ли я его использовать? Если вы просто хотите узнать о скорости, просто проигнорируйте мой комментарий.
все, что я могу сказать, Пожалуйста, будьте очень умны о том, когда использовать троичный ? : оператор. Это может быть как благословение, так и проклятие для читаемости.
спросите себя, если вы найдете это легче читать перед использованием
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% не уверены, что это лучше. Это боль, чтобы исправить, когда он прослушивается также я думай
Я ожидал бы, что на большинстве компиляторов и целевых платформ будут случаи, когда "если" быстрее и случаи где ?: более быстрый. Будут также случаи, когда одна форма более или менее компактна, чем другая. В каких случаях пользу той или иной форме будут различаться между компиляторами и платформами. Если вы пишете критичный для производительности код на встроенном микропроцессоре, посмотрите, что компилятор генерирует в каждом случае, и посмотрите, что лучше. На "основном" ПК, из-за кэширования проблемы, единственный способ увидеть, что лучше, - это сравнить обе формы в чем-то похожем на реальное приложение.
во время реверсирования некоторого кода (который я не помню, несколько лет назад) я видел однострочную разницу между машинным кодом :? а если-иначе.
Don't remember much but it is clear that implementation of both is different.
но я советую вам не выбирать один из них b'coz своей эффективности, выбирать в соответствии с читабельностью кода или вашим удобством. Счастливого Кодирования
тернарный оператор всегда возвращает значение. Поэтому в ситуации, когда вы хотите, чтобы некоторые выходное значение из результата, а есть только 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 позволяет избежать.
вы не обязаны ставить все это на одну строку: -
x = y==1 ? 2 :// else 3;
это намного яснее, чем if/else, потому что вы можете сразу увидеть, что обе ветви приводят к назначению X.
В C тернарный оператор " ? : "можно построить условные выражения вида
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 (a>b) x=a; else x=b;
**, следовательно, нет никакой разницы между этими двумя. Это для программиста написать легко, но для компилятора оба одинаковы.*