문제

두 가지 조건(OR 연산자로 구분)이 있는 if 문이 있습니다. 조건 중 하나는 +70%의 상황을 다루고 두 번째 조건보다 처리/실행하는 데 훨씬 적은 시간이 걸리므로 속도를 위해 다음만 원합니다. 첫 번째 조건이 false로 평가되면 두 번째 조건이 처리됩니다.

첫 번째 조건(더 빠른 조건)이 if 문에 먼저 나타나도록 조건을 주문하면 이 조건이 충족되고 true로 평가되는 경우 두 번째 조건도 처리됩니까?

if ( (condition1) | (condition2) ){
  // do this
}

아니면 첫 번째 조건이 false로 평가되는 경우 두 번째 조건만 확인하려면 두 개의 if 문을 중첩해야 합니까?

if (condition1){
  // do this
}else if (condition2){
  // do this
}

저는 PHP로 작업하고 있지만 이것이 언어에 구애받지 않을 수 있다고 가정합니다.

도움이 되었습니까?

해결책

C, C++, C#, Java 및 기타 .NET 언어의 경우 부울 표현식은 충분한 정보가 알려지면 즉시 평가되지 않도록 최적화됩니다.

난독화된 코드를 수행하는 오래된 방법은 이를 사용하여 다음과 같은 if 문을 만드는 것이었습니다.

a || b();

"a"가 참이면 "b()"는 평가되지 않으므로 다음과 같이 다시 작성할 수 있습니다.

if(!a)
    b();

그리고 마찬가지로:

a && b();

될 것이다

if(a)
    b();

참고하세요 이것은 ||에만 유효합니다 및 && 운영자.두 연산자 | 및 &는 각각 비트 OR, 및 And이므로 "최적화"되지 않습니다.

편집하다:다른 사람들이 언급했듯이 단락 논리를 사용하여 코드를 최적화하는 데 시간을 제대로 투자하는 경우는 거의 없습니다.

먼저 명확성을 추구하십시오. 왜냐하면 읽고 이해하기가 더 쉽기 때문입니다.또한 너무 영리하게 용어를 재정렬하면 뚜렷한 이유 없이 완전히 다른 동작이 발생할 수 있습니다.

둘째, 최적화를 시도하세요. 단, 타이밍과 프로파일링 이후에만 가능합니다.너무 많은 개발자가 프로파일링 없이 조기 최적화를 수행합니다.대부분의 경우 완전히 쓸모가 없습니다.

다른 팁

거의 모든 언어는 단락 평가를 수행합니다.즉, 두 번째 조건은 반드시 필요한 경우에만 평가됩니다.이를 위해 대부분의 언어에서는 단일 파이프(|)가 아닌 이중 파이프(||)를 사용합니다.

보다 http://en.wikipedia.org/wiki/Short-circuit_evaluation

C, C++ 및 Java에서 다음 명령문은 다음과 같습니다.

if (condition1 | condition2) {
  ...
}

매번 두 조건을 모두 평가하고 전체 표현식이 참인 경우에만 참이 됩니다.

성명서:


if (condition1 || condition2) {
  ...
}

평가할 것이다 condition2 경우에만 condition1 거짓입니다.조건2가 함수이거나 부작용이 있는 다른 표현식인 경우 차이는 중요합니다.

그러나, 다음과 같은 차이점은 없습니다. || 사건과 if/else 사례.

최근에 이러한 유형의 질문, 즉 n차 최적화에 대한 질문을 많이 보았습니다.

나는 그것이 특정 상황에서 의미가 있다고 생각합니다.

  1. 계산 조건 2는 정시간 연산이 아닙니다.
  2. 당신은 엄격한 교육 목적을 요구하고 있습니다. 당신은 3us를 구하기 위한 것이 아니라 언어가 어떻게 작동하는지 알고 싶어합니다.

다른 경우에는 조건을 반복하거나 확인하는 "가장 빠른" 방법에 대해 걱정하는 것은 어리석은 일입니다.기록 가능한(그러나 중요하지 않은) 차이를 확인하기 위해 수백만 번의 시도가 필요한 테스트를 작성하는 대신 명확성에 집중하세요.

다른 사람(당신이 될 수도 있습니다!)이 한 달 또는 1년 후에 이 코드를 집어들 때 가장 중요한 것은 명확성입니다.

이 경우 첫 번째 예는 더 짧고 명확하며 반복할 필요가 없습니다.

에 따르면 이 기사 PHP는 단락 평가를 수행합니다. 즉, 첫 번째 조건이 충족되면 두 번째 조건도 평가되지 않습니다.(기사에서) 테스트하는 것도 매우 쉽습니다.

<?php
/* ch06ex07 – shows no output because of short circuit evaluation */

if (true || $intVal = 5) // short circuits after true
{

echo $intVal; // will be empty because the assignment never took place
}

?>

단락은 최적화를 위한 것이 아닙니다.주요 목적은 작동하지 않지만 읽을 수 있는 테스트를 생성하는 코드 호출을 방지하는 것입니다.예:

if (i < array.size() && array[i]==foo) ...

array[i]는 i가 범위를 벗어나서 프로그램이 충돌하는 경우 액세스 위반이 발생할 수 있습니다.따라서 이 프로그램은 확실히 평가의 단락에 의존하고 있습니다!

나는 이것이 최적화 문제보다 훨씬 더 자주 이런 식으로 표현식을 작성하는 이유라고 생각합니다.

최적화 목적으로 단락을 사용하는 것은 과도한 경우가 많지만, 이를 사용해야 할 다른 설득력 있는 이유가 확실히 있습니다.그러한 예 중 하나(C++)는 다음과 같습니다.

if( pObj != NULL && *pObj == "username" ) {
    // Do something...
}

여기서 단락은 다음을 보장하기 위해 사용됩니다. pObj 역참조하기 전에 할당되었습니다.이는 중첩된 것보다 훨씬 더 간결합니다. if 진술.

이것은 언어에 구애받지 않는 태그가 지정되어 있으므로 차임하겠습니다.Perl의 경우 적어도 첫 번째 옵션으로 충분합니다. 저는 PHP에 익숙하지 않습니다.왼쪽에서 오른쪽으로 평가하고 조건이 충족되자마자 삭제됩니다.

적절한 최적화를 갖춘 대부분의 언어에서는 전자가 제대로 작동합니다.

그만큼 | PHP의 비트 연산자입니다.그것은 의미하지 않는다 $a OR $b, 정확히.이중 파이프를 사용하고 싶을 것입니다.그리고 그렇습니다. 앞서 언급했듯이 PHP는 단락 평가를 수행합니다.비슷한 방식으로, 첫 번째 조건이 && 절이 false로 평가되면 PHP는 절의 나머지 부분도 평가하지 않습니다.

VB.net에는 "OrElse"와 "AndAlso"라는 두 가지 멋진 표현이 있습니다.

OrElse는 처음으로 True 평가에 도달하면 자체적으로 단락되어 원하는 코드를 실행합니다.

If FirstName = "Luke" OrElse FirstName = "Darth" Then
   Console.Writeline "Greetings Exalted One!"
End If

AndAlso는 처음으로 False 평가를 수행할 때 자체적으로 단락을 일으키고 블록 내의 코드를 평가하지 않습니다.

If FirstName = "Luke" AndAlso LastName = "Skywalker" Then
   Console.Writeline "You are the one and only."
End If

나는 이 두 가지가 모두 도움이 된다고 생각합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top