2016-12-03 48 views
1

我今天在工作的時候在想:用continue狀態有沒有更快的方法來獲得結果?php - 繼續狀態的性能

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

更快普通循環與的if/else或使用繼續是更快跳躍的結果?

我在問,因爲性能和優化。

+3

這將是一個非常差別不大,所以我寧願集中精力優化的東西,實際上很重要。儘管如此,如果你只是想要奇數,你可以做'$ i + 2'而不是'$ i ++'。 – Qirel

+0

@Qirel我知道數學的循環,比如'$ I + 2',但我把這個像例子。我在想,當你用真正的循環來處理一堆數據,循環中有很多循環,mutch會更快,什麼是什麼? –

+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循環,以減少測試次數

測量每一個變化

例如稍微修改您的代碼,以計算在範圍偶數和奇數的數目的版本[-N,N],不包括0:

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"; 

我們當然可以代替用簡單的公式,這整個循環(這是高層次算法優化),還是讓我們嘗試用循環的工作:

平均時間我多次運行主機上:9.1秒

應用1 ST和第二法則:

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++; 

時間: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我發現你的第二個測試是比別人快。最後一個測試(7.0)爲我運行9.57s和第二個8.2s。在PHP5.6就像你描述。有趣! –

+1

@IvijanStefanStipić其可能PHP7引入了一些優化這讓'如果'%快於'&',也可能是錯誤的同時取得'&'然後慢'如果'%:)我會嘗試使用'(INT)'鑄件。無論如何,這就是爲什麼你必須衡量一切 –