2014-02-25 41 views
-1

我有兩個數組,$posters (945 records)$stats_results(6000 records)。我將這兩個數組相互比較,以查找$posters數組中的記錄到$stats_results數組。一切正常,但需要90秒或更長時間。我怎樣才能使這個過程更快。這是我所做的。比較php中的大數據集

for ($j=0; $j < count($posters); $j++)//945 records 
    { 
    for ($i=0; $i < count($stats_results) ; $i++)//6000 records 
    { 
     if($stats_results[$i]['path'] == '/'.$posters[$j]['path']) 
     { 
     if(date('Ymd',strtotime($stats_results[$i]['start_date']))>=date('Ymd',strtotime($posters[$j]['start_date'])) && date('Ymd',strtotime($stats_results[$i]['start_date']))<=date('Ymd',strtotime($posters[$j]['end_date']))) 
     { 
      $stats[]=array(
       //I am storing filtered value in the array 
      ); 
     } 
    } 
    } 

正如我所說的一切工作正常。沒有mameory問題。有沒有更好的方法來做到這一點? 在此先感謝。

基於建議的改進代碼。它工作正常:

$posters_stats=array(); 
foreach ($posters as $key => $value) 
{ 
    $path = '/'.$value['Identifier']; 
    $posters_stats[$path]=array(
    'sdate'=>date('Ymd',strtotime($value['Presentation_Date'])), 
    'enddate'=>date('Ymd',strtotime($value['Expiry_Date'])) 
); 
} 
foreach ($stats as $key => $stats_result) 
{ 
    if(isset($posters_stats[$stats_result["path"]])) 
    { 
    if(strtotime($stats_result["date"])>=strtotime($posters_stats[$stats_result["path"]]['sdate'])) 
    { 
     echo "<pre>"; 
     print_r($stats_result); 
    } 
    }else{ 
     echo "<pre>"; 
     print_r($stats_result); 
    } 
} 

謝謝大家的貢獻:)

+3

將你的調用放到'for'語句之外的'count()'。你有6495個電話給它,你只需要2. –

+6

這個問題似乎是脫離主題,因爲它是一個代碼審查請求。這更適合http://codereview.stackexchange.com –

+0

如果這些記錄來自數據庫,或者重新考慮用於存儲它們的數據庫設計,請在'MySQL'級別比較這些記錄。儘管如此,在PHP中進行大約500萬次比較並不理智。 – CodeAngry

回答

2

我想你可以改變你的$海報陣列以下形式:

$海報[$ PATH =陣列( 「起始日期」=>」 ... 「」 END_DATE 「=>」 .. 「);

那麼你可以使用

foreach ($stats_results as $key => $stats_result) 
{ 
     if(array_key_exist($stats_result["path"] ,$posters)) 
     ... 
} 

更快的將是

foreach ($stats_results as $key => $stats_result) 
{ 
     if(isset($posters[$stats_result["path"]])) 
     ... 
} 

所以你只有945回合,而不是945 * 6000。

+0

非常感謝您的建議。我會實施這個,看看它有什麼不同。非常感謝。 – Dharmesh

+0

不客氣。 – user3351733

+0

你真棒:-) – Dharmesh

0
foreach ($posters as &$poster) { 

    $stats[] = array_filter($stats_results, function($item) use ($poster) { 

     return 
      ($item['path'] == '/' . $poster['path'] && 
      $item['start_date'] >= $poster['start_date'] && 
      $item['start_date'] <= $poster['end_date']; 

    }); 

} 

使用array_filter與lambda函數。我不確定這是你想要的,但是這個片段會添加到符合條件的$ stats_results的$ stats。這可以避免增加不必要的變量($ j和$),這樣可以避免每次計算元素的數量,這可以避免增加不必要的變量($ j和$一世)。不能避免瘋狂的嵌套循環,但更具可讀性。

+0

foreach比cicle慢,最好用它 –

+0

不,它不是。 [http://stackoverflow.com/questions/3430194/performance-of-for-vs-foreach-in-php]。 –

+0

謝謝大家的建議。我會採取所有建議,並組織我的代碼。非常感激。 – Dharmesh