2012-02-01 74 views
1

我一語計數器功能類的一部分,我想,以適應運行非常大的數據集如何使我的短語計數器運行速度更快

<?php 
private static function do_phrase_count($words, $multidim, $count, $pcount){ 
     if($multidim === false){ 
      $words = array($words); 
     } 

     $tally = array(); 
     $arraycount = 0; 
     foreach($words as $wordgroup){ 
      $max = count($wordgrounp) - $pcount; 
      for($x = 0; $x < $max; $x++){ 
       $cutoff = $x + $pcount; 
       $spacekey = false; 
       $phrase = ''; 
       $z = 0; 
       for($y = $x; $y < $cutoff; $y++){ 
        if($spacekey) $phrase .= ' '; 
        else $spacekey = true; 
        $phrase .= $wordgroup[$y + $z]; 
        $z++; 
       } 
       if(isset($tally[$phrase])){ 
        $tally[$phrase]++; 
        $arraycount++; 
       } 
       else $tally[$phrase] = 1; 
       if($arraycount > 99999){ 
        arsort($tally); 
        $tally = array_slice($tally, 0, 50000); 
        $arraycount = 49999; 
       } 
      } 
     } 
     arsort($tally); 
     $out = array_slice($tally, 0, $count); 
     return $out; 
} 
  • $的話是話的數組檢查
  • $ multidim是布爾表示如果該陣列被級聯或平坦
  • $計數是要被返回的元素數
  • $ pcount是詞語的短語中的數

隨着每次迭代,array_key_exists變慢,所以在某個點我需要減小計數數組的大小。

我正在考慮使用限制(100K)來阻止腳本添加新數組元素到$ tally,或者甚至使用總詞的百分比,但是當我停止向數組添加新元素後,我失去了跟蹤可能會出現的趨勢。 (如果我正在分析整年的數據,到6月份的時候,我將無法將「夏令時」看作趨勢)。

任何人都有一個解決方案,以便如何限制我的理貨數組,以保持腳本不變而不會失去追蹤趨勢的能力?

更新:我根據您的建議更改了腳本。感謝您的幫助。我也想出了一個解決方案來減少陣列的大小。

+0

什麼是您的內存使用情況的樣子,當事情變得顯著慢?你是否遇到交換空間? – sarnold 2012-02-01 03:00:13

+0

我將不得不重新運行,並讓你知道..它似乎在200megs左右緩慢。 300megs需要比200megs數據長5倍。我也必須在64位系統上試試這個..現在在32上運行它 – 2012-02-01 03:05:35

回答

2
if(isset($tally[$phrase])) 
    $tally[$phrase]++; 
else 
    $tally[$phrase] = 1; 

應該快於array_key_exists

PS:測試樣品

function genRandomString($length) { 
    $characters = 'abcdefghijklmnopqrstuvwxyz'; 
    $string = '';  
    for ($p = 0; $p < $length; $p++) { 
     $string .= $characters[mt_rand(0, strlen($characters)-1)]; 
    } 
    return $string; 
} 
function microtime_float() 
{ 
    list($usec, $sec) = explode(" ", microtime()); 
    return ((float)$usec + (float)$sec); 
} 
$len = 1000000; $str = genRandomString($len); 
$tally = array(); 
$stamp1 = microtime_float(); 
for($i=0; $i<$len; $i++) 
{ 
    if(array_key_exists($str[$i], $tally)) 
     $tally[$str[$i]]++; 
    else 
     $tally[$str[$i]] = 1; 
}  
echo microtime_float() - $stamp1 . '<br />'; 
$tally = array(); $stamp1 = microtime_float(); 
for($i = 0; $i<$len; $i++) 
{ 
    if(isset($tally[$str[$i]])) 
     $tally[$str[$i]]++; 
    else 
     $tally[$str[$i]] = 1; 
}  
echo microtime_float() - $stamp1 . '<br />'; 

結果:

0.80751395225525 
0.44111108779907 

當然,鍵的量在此限制。

+0

謝謝;)這應該有所幫助 – 2012-02-01 03:06:48

+1

如果這是真的,那非常可悲。 – sarnold 2012-02-01 03:11:11

3

除了Cheery的回答,請從for循環中刪除count($var)。每次迭代都會不必要地重新計算$ var的大小。

$groupsize = count($wordgroup) - $pcount; 

for($x = 0; $x < $groupsize; $x++){ 
    //... 

報價:God kills a kitten every time you call count() inside a loop.

+0

大聲笑,小貓+1 +1 – motto 2012-02-01 05:36:34

+0

@Josh我手上有很多血,然後:( – 2012-02-02 21:45:53

相關問題