카테고리 없음

[C ++] "if, if, if"또는 "if, else if, else if, else"[종료 됨]

행복을전해요 2020. 12. 9. 12:47

컴파일러는 두 버전 모두에 대해 동일한 코드를 생성합니다. 그러나 두 번째 버전 과 비교하면 유지 관리 측면 에서 첫 번째 버전이 더 좋습니다 .

return명령문이 발견 되면 코드가 종료됩니다 . 그래서 else다가오는 if. 개발자가 코드를 더 잘 이해하게합니다.

또한 이것이 리터럴 코드라면 여전히 축소 할 수 있습니다.

bool Test(SampleType sample)
{
  return (SubTest1(sample) && SubTest2(sample) && SubTest3(sample));
  }
  
-------------------

나는 이것을 할 것이다 :

return SubTest1(sample) && SubTest2(sample) && SubTest3(sample);

이것은 성능을 향상 시키지는 않지만 기능이하는 일이 더 분명 할 수도 있고 그렇지 않을 수도 있습니다.

-------------------

둘 다 동작 측면에서 완전히 동일하며 컴파일러는 둘 모두에 대해 동일한 기계 코드를 내 보냅니다.

가독성 측면에서 그다지 다르지 않습니다. 둘 다 동일한 양의 중첩을 가지고 있습니다. 조기 복귀가없는 경우 깊은 중첩으로 이어지는 경우와 비교하십시오 .

-------------------

가독성 측면에서

bool Test( SampleType sample )
{
    return SubTest1( sample )
            && SubTest2( sample )
                    && SubTest3( sample );
                    }
                    

두 가지 옵션보다 훨씬 명확합니다. 그렇지 않으면 else에서 조건 중 하나가 충족되면 다른 조건은 테스트되지 않음을 분명히해야합니다.

-------------------

둘 다 동일합니다. 컴파일러는 동일한 기계 코드가 생성되도록 최적화하는 방법을 알아낼 것입니다. 읽기 쉽기 때문에 첫 번째 코드를 뽑아 낼 것입니다.

-------------------

나는 그것이 성능에 어떤 차이를 만들 것이라고 상상할 수 없습니다.

나는 그들이 독립적 인 테스트라면 첫 번째 테스트를 사용할 것이고, 당신은 그들이 성공한 후에 그만두고 싶고, 논리적 대안 세트 중에서 선택한다면 두 번째 테스트를 중단하고 싶을 것입니다.

-------------------

내가 아는 한 결과 기계 코드에는 차이가 없습니다. 그 외에 누가 신경 쓰나요? 이 코드에 성능 문제가 있습니까? 성능은 일반적으로 프로젝트가 끝날 때까지 맡겨야하는 어려운 주제이며, 성능 문제가있는 경우에만 사전에 생각할 수있는 위치가 아니라 실제로 존재하는 위치에서 찾아 수정해야 합니다.

-------------------

대부분 컴파일러가 결과 코드를 최적화하는 방법에 따라 다릅니다.

if (.)는 일반적으로 compare_to_zero 명령어와 조건부 점프로 변환됩니다.

귀하의 경우, 이것은

CMP(c1)
RETZ
CMP(c2)
RETZ
CMP(c3)
RETZ

또는 (else-s와 함께)

   CMP(c1)
   JNZ(a1)
      RET
      a1:CMP(c2)
         JNZ(a2)
            RET
            a2:CMP(c3)
               JNZ(a3)
                  RET
                  a3:RET
                  

옵티마이 저의 두 번째 패스는 점프 체인을 확인하고, then / else (및 Z / NZ)가 점프를 건너 뛰고 "다음으로 점프"하는 지점에서 정확히 이전 코드를 제공합니다.

-------------------

언어 및 주변 API에 따라 다릅니다.

첫 번째 해결책은 전형적인 명령 적 접근 방식이며, 초점은 무언가를 확인하는 행위에 있습니다. a이면 중단, b이면 중단, c이면 중단, 성공입니다.

두 번째 해결책은보다 기능적인 앞치마이며, 수학적 정의에서 중괄호로 읽을 수 있습니다 (예 :) fac(n) = { n <= 1: 1, n > 1: n * fac(n-1).

환경에 맞는 솔루션을 선택해야합니다. Java, Python 등에서는 첫 번째입니다. 루비에서는 두 번째가 괜찮을 수 있습니다.

-------------------

"1 개의 진입 지점, 1 개의 출구 지점"이라는 좋은 관행이 있습니다. 함수에서 하나의 리턴 만 갖는 것이 더 낫다는 것을 의미합니다 .

지금은 함수가 간단하지만 앞으로는 더 커지고 더 복잡해지고 해제해야하는 임시 변수를 할당 할 수 있습니다.

따라서 모든 곳에서 모범 사례를 사용하는 것이 좋습니다. 이것은 인간의 실패에 대한 방어 인 "방어 적 프로그래밍"이라고 불립니다.

다음과 같이 작성합니다.

bool Test(SampleType sample)
{
  bool bRet = true; // by default, set it to the most "defensive" value which will cause the less harm or make the problem evident
  
    // in the future, you may have inits and allocations here
    
      if ( !SubTest1(sample) )
          bRet = false; // don't match
            else if ( !SubTest2(sample) )
                bRet = false; // don't match
                  else if ( !SubTest3(sample) )
                      bRet = false; // don't match
                        else
                            ; // bRet stays true
                            
                              // thanks to the single point of exit, you can do things like that
                                if (bRet)
                                     log("... match");
                                       else
                                            log("...no match")
                                            
                                              // here you clean temporary resources...
                                              
                                                return bRet;
                                                }
                                                

성능을 향상시키려는 경우 가장 좋은 방법은 SubTestX 함수를 최상의 순서로 배치하여 가장 자주 일치하지 않는 함수가 첫 번째가되도록하는 것이므로 일치하지 않는 것을 찾는 데 필요한 테스트가 줄어 듭니다.



출처
https://stackoverflow.com/questions/7414949