PHP массовое использование памяти (30 ГБ) с использованием ассоциативных массивов

#php #arrays #memory

#php #массивы #память

Вопрос:

Я создаю скрипт, который требует подсчета количества вхождений каждого слова в каждый файл, из примерно 2000 файлов, каждый из которых составляет около 500 КБ.

Таким образом, это 1 ГБ данных, но использование MySQL превышает 30 ГБ (затем оно заканчивается и заканчивается).

Я отследил причину этого в моем свободном использовании ассоциативных массивов, которое выглядит следующим образом:

 for($runc=0; $runc<$numwords; $runc  )
 {
 $word=trim($content[$runc]);

 if ($words[$run][$word]==$wordacceptance amp;amp; !$wordused[$word])
  {
  $wordlist[$onword]=$word;
  $onword  ;
  $wordused[$word]=true;
  }

 $words[$run][$word]  ; //  1 to number of occurances of this word in current category
 $nwords[$run]  ;
 }
 

$run — это текущая категория.

Вы можете видеть, что для подсчета слов я просто добавляю их в ассоциативный массив $words[$run][$word]. Которое увеличивается с каждым появлением каждого слова в каждой категории файлов.

Затем $wordused[$word] используется, чтобы убедиться, что слово не добавляется дважды в список слов.

$wordlist — это простой массив (0,1,2,3 и т.д.) со списком всех используемых разных слов.

Это потребляет гигантские объемы памяти. Есть ли более эффективный способ сделать это? Я рассматривал возможность использования таблицы памяти MySQL, но я хочу сделать все это на PHP, чтобы он был быстрым и переносимым.

Комментарии:

1. Я не понимаю, как код, который вы показываете, может привести к массовому использованию памяти MySQL?

2. У меня не так много данных, поэтому я не могу их протестировать: D. Но как метод PHP array_count_values складывается с памятью и обработкой?

3. Объединение array_count_values — это хорошо, я буду использовать это для подсчета слов после объединения и сортировки массивов.

Ответ №1:

Вы пробовали встроенную функцию для подсчета слов?
http://hu2.php.net/manual/en/function.str-word-count.php

РЕДАКТИРОВАТЬ: или используйте explode, чтобы получить массив слов, обрезать все с array_walk помощью , затем sort , а затем перейти с for помощью, и подсчитать вхождения, и если в списке появляется новое слово, вы можете flush указать количество вхождений, поэтому нет необходимости учитывать, какое слово было ранее.

Комментарии:

1. Не знал об этом, но не похоже, что он может подсчитывать вхождения слова. Только количество разных слов или возвращает список разных слов. Но мне нужно количество вхождений каждого слова.

2. Выполните метод после «EDIT:», я думаю, вы можете отсортировать входные данные, а затем посчитать. Вам не нужен учет , если входные данные отсортированы.

3. Хммм … разбиение слов, объединение массивов (из разных файлов одной категории) и последующая сортировка могут просто сработать. Тогда нет необходимости в ассоциативном массиве.

4. Что вы имеете в виду, говоря об использовании flush? Я не понимаю, как это будет использоваться там.

5. При сбросе я имел в виду: вам не нужно подсчитывать количество вхождений в php, вы можете просто записать это где-нибудь. Таким образом, нет $ counts[«foo»] = 45; $ counts [«bar»] = 71; и т.д. Просто запишите эти числа в файл или стандартный вывод.