Как заставить мой счетчик фраз работать быстрее - PullRequest
1 голос
/ 01 февраля 2012

У меня есть функция счетчика фраз как часть класса, который я хотел бы адаптировать для запуска очень больших наборов данных

<?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;
}
  • $ words - это массив слов для проверки
  • $ multidim - логическое значение, показывающее, является ли массив каскадным или плоским
  • $ count - количество возвращаемых элементов
  • $ pcount - количество слов в фразе

С каждой итерацией array_key_exists становится медленнее, поэтому в определенный момент мне нужно уменьшить размер массива.

Я рассматривал возможность использования ограничения (100K) для остановки скриптаот добавления новых элементов массива в $ tally, или даже использования процента от общего числа слов, но после того, как я перестал добавлять новые элементы в массив, я теряю способность отслеживать тенденции, которые могут появиться.(Если я анализирую данные за весь год, то к тому времени, когда я доживу до июня, я не смогу рассматривать «летнее время» как тренд).

У кого-нибудь есть решение относительно того, какограничить мой массив подсчетов, чтобы скрипт не зависал, не теряя возможности отслеживать тренды?

ОБНОВЛЕНИЕ: Я изменил скрипт в соответствии с вашими предложениями.Спасибо за помощь.Я также нашел решение для сокращения размера массива.

Ответы [ 2 ]

3 голосов
/ 01 февраля 2012

В дополнение к ответу Cheery, удалите count($var) из цикла for.С каждой итерацией вы без необходимости пересчитываете размер $ var.

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

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

Цитата: Бог убивает котенка каждый раз, когда вы вызываете count () внутри цикла.

2 голосов
/ 01 февраля 2012
if(isset($tally[$phrase])) 
   $tally[$phrase]++;
else 
   $tally[$phrase] = 1;

Это должно быть быстрее, чем array_key_exists

ps: тестовый образец

function genRandomString($length) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyz';
    $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

Конечно, суммаключи здесь ограничены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...