Сжимается ли хеш в Perl при удалении элементов? - PullRequest
8 голосов
/ 25 сентября 2008

Уменьшает хеш в Perl при удалении элементов.

Точнее говоря, у меня была унаследованная Perl-программа, которая анализировала огромный файл (1 ГБ) и загружала хэш хэшей. он сделал бы то же самое для другого файла, а затем сделал бы сравнение различных элементов. Во время этого процесса потребление памяти было огромным, и хотя я добавил удаление элементов хеша, если они использовались, потребление памяти, по-видимому, не изменилось.

Сценарий был чрезвычайно медленным и такой боров памяти. Я знаю, что это не было хорошо разработано, но есть какие-нибудь идеи об использовании хэш-памяти?

Ответы [ 6 ]

11 голосов
/ 25 сентября 2008

Возможно, вы захотите проверить что-то вроде DBM :: Deep . Это связано с тем, что упоминал Майкл, так что вам не нужно об этом думать. Все хранится на диске, а не в памяти. Просто не требуется более изящный сервер баз данных.

Кроме того, если вы хотите отследить узкое место в производительности, посмотрите Devel :: NYTProf , новую горячность в профилировании Perl, появившуюся в Нью-Йорке Times .

7 голосов
/ 25 сентября 2008

Как правило, Perl не может вернуть память операционной системе. Однако он может использовать внутреннюю память повторно, что может уменьшить объем памяти, необходимый программе.

См. Perlfaq3: Как освободить массив или хэш, чтобы программа сжималась?

Если память, используемая хешами, чрезмерна (т. Е.> Физическая память), вы можете tie передать их в файл на диске. Это значительно уменьшит использование вашей памяти, но имейте в виду, что доступ к структуре на диске намного медленнее, чем доступ к структуре в памяти. (То же самое происходит с диском.)

5 голосов
/ 25 сентября 2008

Относительно конкретного вопроса: Нет, удаление хеш-ключей не уменьшает потребление памяти вашей программой.

Относительно более общего случая: Подавляющее большинство программ и языков будут продолжать удерживать память, которую они ранее использовали, но в настоящее время не используют. Это потому, что запрос выделения памяти операционной системой является относительно медленной операцией, поэтому они сохраняют ее на тот случай, если она понадобится позже.

Итак, если вы хотите улучшить ситуацию, вам нужно уменьшить пиковый объем памяти, необходимый вашей программе, будь то путем пересмотра ваших алгоритмов, чтобы вам не требовался одновременный доступ к большому количеству данных, с помощью дисковое хранилище (такое как вышеупомянутый DBM :: Deep) или путем освобождения пространства от ненужных переменных обратно в perl (разрешите им выйти из области действия или установите для них undef ), чтобы его можно было использовать повторно 1007 *

5 голосов
/ 25 сентября 2008

Если ваш хэш действительно гигантский, то лучшей стратегией, вероятно, является использование хэша на диске, и операционная система должна беспокоиться о том, чтобы что-то было в памяти и из нее. Мне особенно нравится Berkeley DB для хранения больших хэшей на диске, а модуль Perl BerkeleyDB предоставляет полнофункциональный интерфейс, включая связанный API.

DBM :: Deep также может использоваться в качестве замены для вставки хэша, но использует свой собственный формат. Это может быть проблемой, если ваша структура должна быть прочитана другими (не Perl) системами.

4 голосов
/ 25 сентября 2008

Обходной путь: разветвите дочерний процесс, который выделяет всю эту память. Позвольте ему передать некоторую совокупную информацию, когда он сделает свое дело; когда разветвленный процесс умирает, его память уходит вместе с ним. Немного боли, но работает в некоторых случаях. Примером, когда это помогает, может быть, если вы обрабатываете много файлов, каждый файл по одному, только несколько файлов имеют большой размер и требуется небольшое промежуточное состояние.

4 голосов
/ 25 сентября 2008

Если входные данные во втором файле нужны только один раз (поскольку они читаются), вы можете сократить использование памяти пополам.

В зависимости от вашего алгоритма, вы можете даже держать открытыми как файловые дескрипторы, так и небольшой хэш неиспользуемых пока еще значений в памяти. Примером может служить слияние или сравнение отсортированных данных - вам нужно только удерживать текущую строку из каждого файла и сравнивать ее друг с другом по мере продвижения, пропуская до тех пор, пока cmp не изменится.

Другой подход может состоять в том, чтобы сделать несколько проходов, особенно если на вашем компьютере установлено одно или несколько ядер, которые в противном случае простаивают. Открытые каналы чтения и подпроцессы передают вам данные в виде управляемых предварительно организованных блоков.

Для более общих алгоритмов вы можете не платить за объем памяти, обменивая ее на стоимость скорости диска.

В большинстве случаев загрузка каждого источника данных в память выигрывает только во время разработки - тогда вы платите за это в размере и / или скорости, когда N становится большим.

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