문제

다음이있는 경우 :

$var = 3; // we'll say it's set to 3 for this example
if ($var == 4) {
    // do something
} else if ($var == 5) {
    // do something
} else if ($var == 2) {
    // do something
} else if ($var == 3) {
    // do something
} else {
    // do something
}

시간의 80%를 말하는 경우 $var 3인가, 진정한 사례를 찾기 전에 사례가 4 건을 겪고 있다는 사실에 대해 걱정하십니까?

나는 작은 사이트에서 그것이 큰 문제가 아니라고 생각하고 있지만, 그 If 문장이 순간에 1000 번을 실행할 때는 어떻습니까?

PHP에서 일하고 있지만 언어가 중요하지 않다고 생각합니다.

도움이 되었습니까?

해결책

레이더 시스템 용 소프트웨어를 작성했을 때 어떻게했는지는 다음과 같습니다. (속도는 레이더에서 중요합니다. 그것은 "실시간"이 실제로 "빠른"대신 "실제"를 의미하는 몇 안되는 곳 중 하나입니다.)

Python 구문으로 전환하겠습니다. 더 쉽고 해석 할 수 있다고 확신합니다.

if var <= 3:
    if var == 2:
        # do something
    elif var == 3:
        # do something
    else: 
        raise Exception
else:
    if var == 4:
        # do something
    elif var == 5:
        # do something
    else:
        raise Exception

if 진술은 평평한 목록 대신 나무를 형성합니다. 이 목록에 조건을 추가하면 나무 중앙 주위를 흔들립니다. 평평한 시퀀스 N 비교는 평균적으로, N/2 단계. 트리는 로그를 취하는 일련의 비교로 이어집니다 (N) 비교.

다른 팁

글쎄, 나는 그것을 믿는다 거의 항상, 예를 들어, 수치 적으로 주문한 값을 갖는 가독성은 비교 지침의 수를 줄임으로써 얻을 수있는 작은 이점을 무시할 수 있습니다.

모든 최적화와 마찬가지로

  1. 작동하게 만들다
  2. 측정하십시오
  3. 충분히 빠르면 내버려 두십시오
  4. 너무 느리면 최적화하십시오

아, 그리고 아마도 Get-Go에서 스위치/케이스를 사용할 것입니다! ;-)

이런 일이 발생하는 전형적인 사례 (게시물에서와 같이 문자 그대로 5 가지 옵션)는 decode_cabac_residual 함수에서 ffmpeg에있었습니다. 프로파일 링 (프로파일 링 전에 최적화하지 않음)이 H.264 비디오 디코딩에 소요 된 시간의 10-15% 이상을 계산 한 것으로 나타났습니다. IF 문은 다양한 유형의 잔차를 디코딩하기 위해 다르게 계산 된 일련의 진술을 제어했습니다. 불행히도 5 가지 유형의 각각에 대해 함수가 5 번 복제 된 경우 코드 크기로 인해 너무 많은 속도가 손실되었습니다. 잔여. 대신 IF 체인을 사용해야했습니다.

프로파일 링은 많은 일반적인 테스트 스트림에서 가능성 측면에서 주문하기 위해 수행되었습니다. 상단은 가장 일반적이며 맨 아래는 가장 일반적이었습니다. 이것은 작은 속도 이득을 주었다.

이제 PHP에서는 위의 예에서와 같이 C에서 얻을 수있는 낮은 수준의 스타일 속도 이득이 훨씬 적습니다.

스위치/케이스 문을 사용하는 것이 분명히 여기로가는 길입니다.

이로 인해 컴파일러 (통역사)는 점프 테이블을 사용하여 비교를 수행하지 않고 오른쪽 지점에 도달 할 수 있습니다. 0, 1, 2,로 인덱싱 된 주소 배열을 생성한다고 생각하십시오. 그러면 단일 작업에서 배열에서 올바른 것을 볼 수 있습니다.

또한, 사례 명령문에서는 신디케이트 오버 헤드가 적기 때문에 더 쉽게 읽습니다.

업데이트: 비교가 스위치 문에 적합한 경우 프로파일 가이드 최적화가 도움이 될 수있는 영역입니다. 현실적인 테스트로드로 PGO 빌드를 실행하면 시스템은 분기 사용 정보를 생성 한 다음이를 사용하여 취한 경로를 최적화 할 수 있습니다.

PHP 질문에 대답하기보다는 조금 더 일반적으로 대답하겠습니다. 어떤 종류의 해석을 거치기 때문에 PHP에 직접 적용되지 않습니다.

많은 컴파일러가 IF-ELIF-ELIF -... 블록을 필요한 경우 블록으로 전환 할 수 있으며 ELIF 파트의 테스트는 충분히 간단합니다 (그리고 나머지 의미는 호환됩니다). 3-4 테스트의 경우 점프 테이블을 사용하여 반드시 얻을 수있는 것은 아닙니다.

그 이유는 CPU의 지점 예측자가 실제로 무슨 일이 일어나는지 예측하는 데 능숙하기 때문입니다. 사실상 발생하는 유일한 일은 지시 페치에 대한 압력이 약간 더 높지만 세계가 산산이 부족하지는 않습니다.

그러나 예를 들어, 대부분의 컴파일러는 $ var가 상수 3임을 인식 한 다음 $ var를 if..elif .. 블록에서 3으로 대체합니다. 이것은 차례로 표현을 일정하게 만들어서 거짓의 사실로 접 힙니다. 모든 잘못된 분기는 Dead-Code Eminator에 의해 사망하고 True에 대한 테스트도 제거됩니다. 남은 것은 $ var == 3의 경우입니다. PHP에 의존 할 수는 없습니다. 일반적으로 $ var의 전파를 할 수는 없지만 일부 콜 사이트에서는 가능할 수 있습니다.

당신은 당신이 호출하는 다양한 코드 블록을 시도 할 수 있습니다. 그런 다음 모든 코드 블록의 오버 헤드가 동일합니다.

Perl 6 :

our @code_blocks = (
  { 'Code Block 0' },
  { 'Code Block 1' },
  { 'Code Block 2' },
  { 'Code Block 3' },
  { 'Code Block 4' },
  { 'Code Block 5' },
);

if( 0 <= $var < @code_blocks.length ){
  @code_blocks[$var]->();
}

코드가 추가 테스트를 수행해야한다면 더 느리게 실행됩니다. 이 코드 섹션에서 성능이 중요하다면 가장 일반적인 사례를 먼저 배치해야합니다.

일반적으로 성능이 충분히 빠른지 확실하지 않은 경우 "측정, 최적화"메소드에 동의하지만 코드가 가능한 한 빨리 실행되어야하고 테스트를 재정렬하는 것만 큼 수정이 쉽습니다. 나는 지금 코드를 빨리 만들고, 당신이 살아 가고 나서 당신의 가정 (예 : 3이 80%의 시간이 80%가 될 것임)이 실제로 정확하다는 것을 보장하기 위해 측정을 할 것입니다.

순전히 평등 분석 인 코드를 사용하면 더 나은 성능을 제공하므로 스위치/케이스로 이동합니다.

$var = 3; // we'll say it's set to 3 for this example
switch($var)
 {
   case 4:
      //do something
      break;
   case 5:
      //do something
      break;
   case:
      //do something when none of the provided cases match (same as using an else{ after the elseif{
 }

이제 더 복잡한 비교를하는 경우 스위치에 중첩하거나 elseif를 사용합니다.

객체 지향 언어에서 옵션이 거대한 IFS를 제공하는 경우 동작을 이동해야합니다 (예 : //do something 블록) 값이 포함 된 객체에.

순서 최적화의 성능 차이 또는 실제로 이진 트리가되도록 재배치하는 것이 큰 차이를 만들 수 있는지 알 수 있습니다. 그러나 나는 PHP (그리고 다른 언어에서는 더 많은 사람들)에서 그것에 대해 생각하기도하기 위해 수천 초에 수백만 번을 가져야한다고 생각합니다.

시간 시간. 조치가 취해지고 $ var가 선택 중 하나가 아닌 위의 IF/Else/Else 문을 실행할 수있는 순간을 몇 번이나 확인하십시오.

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