Стристр и скорость - PullRequest
       1

Стристр и скорость

0 голосов
/ 08 сентября 2010

У меня есть два файла: файл размером около 5 МБ и файл размером около 66 МБ.Мне нужно выяснить, есть ли какие-либо вхождения строк в файле a, внутри файла b, и, если да, записать их в файл c.

Вот как я сейчас работаю:1004 *

Проблема в том, что он работает (успешно) более часа, и, возможно, 3000 строк в 160 000 в меньшем файле.Есть идеи?

Ответы [ 3 ]

0 голосов
/ 08 сентября 2010

Попробуйте использовать ob_flush () и flush () в цикле.

foreach($small_list as $one_line)
{
 if(stristr($big_list, $one_line) != FALSE) 
    {
    fwrite($fh, $one_line);
    echo "record found: " . $one_line ."<br>";
    }  
       @ob_flush();
        @flush();
        @ob_end_flush(); 
}
0 голосов
/ 08 сентября 2010

Создание массивов с хэшами в виде индексов:

Чтение в файл a.csv построчно и сохранение в a_hash[md5($line)] = array($offset, $length) Чтение в файл b.csv построчно и сохранение в b_hash[md5($line)] = true

Используя хеши в качестве индексов, вы автоматически не получите дублирующиеся записи.

Затем для каждого хеша, который имеет индексы как a_hash, так и b_hash, считанные из содержимого файла (используя смещение и длинухранится в a_hash), чтобы вытащить фактический текст строки.Если вы недовольны хеш-коллизиями, сохраните смещение / длину для b_hash и проверьте с помощью stristr.

Это будет работать намного быстрее и использовать намного, далеко, FAR меньше памяти.

Если вы хотите еще больше снизить требования к памяти и не возражаете против проверки дубликатов, то:

Строка в файл a.csv построчно и сохранение в a_hash[md5($line)] = false
Чтение в файл b.csv построчнострока, хеш строки и проверьте, существует ли в a_hash.
Если a_hash[md5($line)] == false, напишите в c.csv и установите a_hash[md5($line)] = true

Пример кода для второго предложения:

$a_file = fopen('a.csv','r');
$b_file = fopen('b.csv','r');
$c_file = fopen('c.csv','w+');

if(!$a_file || !$b_file || !$c_file) {
    echo "Broken!<br>";
    exit;
}

$a_hash = array();

while(!feof($a_file)) {
    $a_hash[md5(fgets($a_file))] = false;
}
fclose($a_file);

while(!feof($b_file)) {
    $line = fgets($b_file);
    $hash = md5($line);
    if(isset($a_hash[$hash]) && !$a_hash[$hash]) {
        echo 'record found: ' . $line . '<br>';
        fwrite($c_file, $line);
        $a_hash[$hash] = true;
    }
}

fclose($b_file);
fclose($c_file);
0 голосов
/ 08 сентября 2010

Попробуйте сначала отсортировать файлы (особенно большие). Затем вам нужно только проверить первые несколько символов каждой строки в b и остановиться (перейти к следующей строке в a), когда вы пройдете этот префикс. Затем вы можете даже указать, где в файле каждый символ является первым (a начинается со строки 0, b начинается со строки 1337, c начинается со строки 13986 и т. Д.).

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