삼항 연산자? : vs if… else


80

C ++에서? : 연산자가 if () ... else 문보다 빠릅니까? 컴파일 된 코드에 차이점이 있습니까?


컴파일러의 최적화 설정에 따라 달라지기 때문에 어려운 질문입니다.
extraneon

3
그것은 확실히 당신이 지점 안에서 무엇을하는지에 달려 있습니다. 조건 연산자 if는 문 을 허용 하는 동안 표현식 만 허용합니다.
Gumbo


8
어떤 사람이 무작위로 내 완벽하게 괜찮은 3 년 된 질문을 편집하기로 결정했습니다. 질문을 다시 작성하여 저와 완전히 다르게 들리며 전체 문제를 무의미하게 만드는 완전히 불필요한 코드를 추가했습니다. 왜냐하면 끊임없는 접기 덕분에 두 샘플 모두 간단한 결과로 줄어들 기 때문입니다. = 5 ". 되 돌리는 중입니다.
Xirdus 2013

답변:


88

컴파일러에 따라 다르지만 최신 컴파일러에는 일반적으로 차이가 없습니다. 그것은 당신이 걱정하지 말아야 할 것입니다. 코드의 유지 관리에 집중하십시오.


1
+1 많은 애플리케이션에서 성능 차이는 실제 덤프 컴파일러에서도 고려할 가치가 없습니다.

4
코드의 유지 관리 가능성에 관해서는 ... 그렇지 않으면 선호합니다. 적어도 나에게는 읽기가 더 쉽습니다.
Exa 2010-08-25

2
@Exa : 상황에 따라 다릅니다. 삼항 연산자는 객체를 초기화 할 때 종종 더 좋습니다.
Nemanja Trifunovic

@Nemanja : 그것이 내가 "적어도 나를 위해"라고 말한 이유입니다. 나는 단지 코드의 가독성을 언급하고 있었다 :)
Exa

1
@kotlinski, 조건부가 if보다 유지 관리가 덜하다는 말은 아닙니다. 위에 링크 된 삼항으로 또는 삼진으로 질문 의 답변에 설명 된대로 둘 다 특정, 다른 상황에서 더 명확 합니다.
ptomato

106

빠르지 않습니다. 일부 표현식에 따라 상수 변수를 초기화 할 수있는 경우 한 가지 차이점이 있습니다.

const int x = (a<b) ? b : a;

.NET으로 동일한 작업을 수행 할 수 없습니다 if-else.


20
@Developer Art : const변수로 는 불가능합니다 .
작업

1
상수가 아닌 변수를 만들고 if / else에 할당 한 다음 새 const 변수를 만들고 상수가 아닌 변수로 구성 할 수 있습니다. 오히려 낭비 적이지만 불가능하지는 않습니다.
Puppy

7
좋은 ol '은 max어떻습니까? const int x = max(a,b);잘 작동합니다.
bobobobo

3
@bobobobo 하! 내가 당신의 코멘트를 읽었을 때 나는 당신이 제안한 명령이 max ? const int x = max(a,b);와우라고 생각했습니다! WTF입니다! 그런 다음 다시 읽고 물음표가 고정 폭이 아님을 알았습니다! 주제를 감안할 때 내가 생각하는 것이 정당하다고 생각합니다. 명령의 일부였습니다! :)
dewd

2
사용할 수 있습니다 const int x = [&] -> int { if (a < b) return b; else return a; }.
LF

43

GCC가 조건부 연산자를 cmov(조건부 이동) 명령으로 바꾸는 동안 if문을 분기로 바꾸는 것을 보았습니다 . 즉, 우리의 경우 조건부 연산자를 사용할 때 코드가 더 빨랐습니다. 그러나 그것은 몇 년 전이었고 오늘날에는 둘 다 동일한 코드로 컴파일 될 것입니다.

동일한 코드로 컴파일된다는 보장은 없습니다. 당신은 항상 다음 성능, 필요한 경우 조치를 . 그리고 측정하여 1. 코드가 너무 느리고 2. 범인이이 특정 코드 덩어리라는 것을 알았을 때 컴파일러가 생성 한 어셈블리 코드를 연구하고 무슨 일이 일어나고 있는지 직접 확인하십시오.

"조건부 연산자를 사용하면 컴파일러가 항상 더 효율적인 코드를 생성합니다"와 같은 황금 규칙을 신뢰하지 마십시오.


2
+1. GCC를 사용하여 PS3 용으로 개발할 때 "if"대신 조건문을 사용하는 것이 분기를 피하는 데 유용했습니다.
Johan Kotlinski

이것은 C 언어에만 해당됩니까? C ++의 표준은 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명령 을 생성하는 것을 분명히 방지 한다고 말합니다 .
Joey.Z

2
@zoujyjs no, C는 같은 규칙을 가지고 있습니다. 그러나 as-if 규칙에 따라 최종 결과가 정확하다면 컴파일러는 자유롭게 속일 수 있습니다. 부작용이없는 한 컴파일러는이 최적화를 수행 할 수 있습니다.
jalf

cmov로 다른 경우 구현하는 방법은 무엇입니까? 값 1로 이동 + 값 2로 cmov?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

1
참고 :이 조언은 구식이며 (cira 2010) gcc 4.4 이상에서는 재현 할 수 없습니다.
ACyclic 2010 년

15

동일하지만 삼항 연산자는 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"를 "one"으로 바꿀 수 있다고 확신합니다.)


8
삼항 연산자도 필요하지 않습니다.printf("Total: %d item%s", cnt, "s" + (cnt==1));
MSalters

@MSalters하지만 문자열 끝에 이중 널을 제공합니다. 이는 이중 널이 무언가를 의미하는 다른 상황에서 문제가 될 수 있습니다 (예 : OPENFILENAME 구조의lpStrFilter 구성원 )
bobobobo

1
@bobobobo : 아니요 . 원본 문자열에서를 %s포함하지 않고 최대 인쇄 \0합니다.
MSalters 2012

@MSalters 어떻게 printf("Total: %d item%s", cnt, "s" + (cnt==1));작동합니까?
Quirk

2
@Quirk : (cnt==1)true 또는 false이며 0 또는 1로 변환됩니다. "s"는 널로 끝나는 문자열에 대한 포인터입니다. 하나를 추가하면 한 문자 (s)를 건너 뜁니다. 따라서 이것은 "s"또는 ""를 인쇄합니다.
MSalters


3

컴파일 된 코드에 관계없이 그들은 의미가 다릅니다. <cond>?<true expr>:<false expr>표현이고 if..else..진술이다.

조건식의 구문이 어색해 보이지만 좋은 것입니다. a를 제공해야 <false expr>하며 두 표현식은 유형 검사됩니다.

에 해당하는 if..else..리스프와 같은 표현 기반, 기능적 언어는, 하스켈는 ? :대신, C ++에서 if..else..문.


2

모든 것을 한 줄에 입력 할 필요가 없습니다.

x = y==1 ?
    2
    :// else
    3;

두 가지 모두 x가 할당되는 것을 즉시 알 수 있기 때문에 if / else보다 훨씬 더 명확합니다.


const를 초기화 할 수도 있습니다
QuentinUK

0

대부분의 컴파일러와 대상 플랫폼에서 "if"가 더 빠른 경우와? :가 더 빠른 경우가있을 것으로 예상합니다. 한 양식이 다른 양식보다 다소 간결한 경우도 있습니다. 어떤 경우에 한 형식을 선호하는지 또는 다른 형식은 컴파일러와 플랫폼에 따라 다릅니다. 임베디드 마이크로에서 성능이 중요한 코드를 작성하는 경우 컴파일러가 각 경우에 생성하는 내용을 살펴보고 어느 것이 더 나은지 확인하십시오. "주류"PC에서 캐싱 문제로 인해 어떤 것이 더 나은지 확인하는 유일한 방법은 실제 응용 프로그램과 유사한 형태로 두 가지 형식을 모두 벤치마킹하는 것입니다.


0

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;

** 따라서이 둘 사이에는 차이가 없습니다. 이것은 프로그래머가 쉽게 작성하기위한 것이지만 컴파일러의 경우 둘 다 동일합니다. *


0

일부 코드를 뒤집는 동안 (몇 년 전 기억하지 못함) 머신 코드 사이에 한 줄 차이가 있음을 보았습니다. 그리고 if-else. Don't remember much but it is clear that implementation of both is different.

그러나 나는 효율성 중 하나를 선택하지 말고 코드의 가독성이나 편의성에 따라 선택하는 것이 좋습니다. 해피 코딩


차이는 그 중 하나가 분기에 대한 고토를 사용 하였다 및 기타 saome 기본 명령어를 사용했는데, 내가 하나가 사용 된 기억하지 않는 ..
페르 베즈 알람

0

삼항 연산자는 항상 값을 반환합니다. 따라서 결과에서 일부 출력 값을 원하고 삼항 연산자를 사용하는 것이 항상 두 가지 조건 만있는 상황에서. 위에 언급 된 조건 중 하나라도 참이 아닌 경우 if-else를 사용하십시오.


6
이것은 정확히 무엇입니까? 무슨 말을하는지 아십니까?
quantum

0

나는 그것이 작동하는 범위 때문에 인라인 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를 인라인하여 .NET a과 동일한 범위에서 유지하는 데 필요한 많은 작업을 절약 할 수 b있습니다. 두 시나리오에서 조건 평가 속도가 거의 같을 가능성이 높지만 범위를 변경하면 피할 수있는 경우 인라인을 고려하여 다른 요소를 고려해야합니다.


그리고 A a(true ? 5 : 10);
Quest

-1

이제 도움을 드릴 수 없습니다. 그 아래에있는 2 차 질문에 도움을 드릴 수 있습니다. 사용 하시겠습니까? 속도 만 알고 싶다면 내 의견을 무시하십시오.

내가 말할 수있는 것은 삼항을 언제 사용할 지에 대해 매우 현명 해지십시오. : 운영자. 가독성에 대한 저주만큼이나 축복이 될 수 있습니다.

사용하기 전에이 정보가 더 읽기 쉬운 지 자문 해보십시오.

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 % 가짜로 만드는 것은 어리석은 것 같습니다. 그러나 그 작은 트릭은 내가 코드의 가독성을 분석하는 데 도움이되었습니다. 내용이 아니라이 샘플에서 보는 연산자의 가독성입니다.

깨끗해 보이지만 보통의 변기와 문 손잡이도 그렇습니다.

제한된 내 경험상, 3 항 연산자에서 필요한 정보를 실제로 신속하게 인도 할 수있는 사람은 거의 없었습니다. 100 % 더 낫다고 확신하지 않는 한 피했습니다. 도청이되었을 때 고치는 것도 고통 스럽습니다.


5
첫 번째 줄은 아마도 읽 int x = x == 1 ? 1 : 2거나 가능 해야합니다int x = (x == 1) ? 1 : 2
Hasturkun 2010-08-25

내 요점은 단순히 코드의 관점을 보여주는 것이었고 한 줄의 깔끔함이 좋습니다. 그러나 CONDITION / ASSIGNEMENT를 보려면 코드의 내용이 가짜 일 수 있습니다. 당신이 보는 것이 무엇인지 발견하고 싶다면 운영자와 위치 만 봅니다. 나는 IF와 ()라는 단어를 본다. 나는 그것이 조건이라는 것을 알고있다. 나는 A = B를 본다? CONDITION : CONDITION 당신은 그것을 직접 발견 했습니까? 내가 아는 대부분의 사람들은 그 프로그램이 그렇지 않습니다. 아마도 그 프로그램을 아는 대부분의 사람들이 저와 같은 신인이기 때문일 것입니다. 당신은 말도 안되는 숫자의 올바른 ofc, 그게 요점입니다.
Proclyon

2
첫 번째 줄에는 괄호가 필요합니다. 아마도 "int x = (y == 1)? 0 : 1;" 또는 "int x = ((y == 1)? 0 : 1);"
supercat

6
미안하지만 과제를 보는 데 문제가 없습니다. 요점을 만들기 위해 예제를 지나치게 복잡하게하기로 선택했다면 그게 문제입니다. x = x = 1;모든 곳에 글을 쓰고 과제가 너무 복잡하고 피해야한다고 불평 하지 않는 이유는 무엇입니까?
UncleBens 2010-08-25

-4

아니요, 정확히 동일한 실행 코드로 변환됩니다.


7
-1 : 어떤 컴파일러의 어떤 버전에서 어떤 플랫폼에서 어떤 코드로?
Puppy

3
DeadMG : 당연히 VB6 컴파일러!
Alex F
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.