2016-12-03 2 views
1

나는 직장에서 오늘 생각하고있었습니다 : continue 상태를 사용하여 결과를 얻는 훨씬 빠른 방법이 있습니까?PHP - 계속 진행 상태의 성능

for ($i=0; $i<5000; $i++) { 
    if (!($i % 2)) { 
     continue; 
    } 
    do_something_odd($i); 
} 

경우/다른와 빠른 일반 루프 아니면 계속 사용하여 빠른 건너 뛰기 결과인가?

성능 및 최적화 때문에 부탁드립니다.

+3

거의 차이가 없으므로 실제로 중요한 문제를 최적화하는 데 주력하고 싶습니다. 그래도 홀수를 원한다면'$ i ++ '대신'$ i + 2'를 쓸 수 있습니다. – Qirel

+0

@Qirel 나는'$ i + 2'와 같은 수학적 루프를 알고 있지만 이것을 예제로 쓴다. 나는 많은 수의 데이터와 함께 실제 루프에서 작업 할 때 루프 내부의 많은 루프를 어떻게 처리 할 것인가를 생각하고있다. –

+0

실제로 제가 게시 한 내용은 잘못되었습니다. 구문은'$ i + = 2'가 아니라'$ i + = 2'입니다. 어느 것이 더 빠른 지 테스트하고 싶다면 벤치 마크를 실행하십시오. – Qirel

답변

1

그래도 어쨌든, 대답을 찾고 있다면 확실하지 : 나는하지 않도록하는 것이 좋습니다

for (...) { 
    if (condition) continue; 
    some work; 
} 

for (...) { 
    if (!condition) some work; 
} 

: 일반적으로

, 사이에 성능 차이가 없습니다 continue, 내가보기에는 덜 읽기 쉽기 때문에, 기본적으로 goto입니다.

물론 첫 번째로 최적화해야 할 것은 고급 알고리즘, 데이터 구조 등입니다. 이 작업을 완료하고 성능을 극대화해야하는 경우 주요 주된 요인은 조건/분기 및 잘못된 예측입니다. 많은 다른 기술은 그것을 위해있다 : 루프 외부

  1. 이동 조건은 여러 사람에
  2. 분할 루프가 가능한 경우
  3. 보통 곱하기, 나누기 및 계수는 비트 현명한 사업자에 비해 매우 느린
  4. 일부 조건이 무점포 문으로 대체 할 수
  5. 취소-rool는 테스트의 수를 최소화하기 위해 루프

측정 0을 제외하고 약간 [-N, N] 범위에서 짝수 및 홀수 번호의 수를 계산하는 코드의 수정 된 버전 예를 들어 모든 변경

:

define('N', 100000000); 

$start = microtime(true); 

$odd_count = 0; 
$even_count = 0; 
for ($i=-N; $i<=N; $i++) 
    if ($i != 0) 
     if ($i % 2 != 0) $odd_count++; 
     else $even_count++; 

$end = microtime(true); 

echo 'odd: '.$odd_count."\n"; 
echo 'even: '.$even_count."\n"; 
echo 'time: '.($end-$start)."\n"; 

물론 우리는 대체 할 수있다 간단한 공식이 전체 루프는 (은 높은 수준의 알고리즘 최적화입니다)하지만, 루프 작업을 시도 할 수 있습니다 :

1을 적용 9.1 초 :

평균 시간 여러 실행에서 내 호스트 일, 2 규칙 :

for ($i=-N; $i<0; $i++) 
     if ($i % 2 != 0) $odd_count++; 
     else $even_count++; 
for ($i=1; $i<=N; $i++) 
     if ($i % 2 != 0) $odd_count++; 
     else $even_count++; 

시간 :

가 3, 4 규칙을 적용 7.7 초 :

for ($i=-N; $i<0; $i++) { 
    $t = $i & 1; 
    $odd_count += $t; 
    $even_count += 1 - $t; 
} 
for ($i=1; $i<=N; $i++) { 
    $t = $i & 1; 
    $odd_count += $t; 
    $even_count += 1 - $t; 
} 

시간 : 7.3 초

그리고 최종 결과 :

for ($i=-N; $i<0;) { 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
} 
for ($i=1; $i<=N;) { 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
    $t = $i++ & 1; $odd_count += $t; $even_count += 1 - $t; 
} 

시간 : 7.0 초

+0

흥미 롭습니다. PHP 7에서는 2 차 테스트가 다른 테스트보다 빠릅니다. 9.57s를 실행하는 나를위한 마지막 테스트 (7.0)와 8.2s.In PHP5.6을위한 2nd는 당신이 설명하는 것과 같습니다. 흥미 롭 군! –

+1

@ IvijanStefanStipić php7은'if %'를 빠르게 만든 다음'&'을 만들거나''''''''''%':를 만든 버그 일 수 있다는 가능성을 가능하게했습니다.''(int) 주조. 어쨌든, 이것이 당신이 모든 것을 측정해야만하는 이유입니다. –

관련 문제