Тернарный оператор: vs if ... else


В C++ есть ?: оператор быстрее, чем если()...еще заявления? Есть ли различия между ними в скомпилированном коде?

14 61

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" в первой строке на "один")

просто чтобы быть немного левша...

x ? y : x = value

назначить стоимостью до y если x не 0 (false).

независимо от скомпилированного кода, они семантически разные вещи. <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;

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

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