Как эффективно сгруппировать большой список URL-адресов по имени хоста в Perl? - PullRequest
1 голос
/ 07 апреля 2010

У меня есть текстовый файл, который содержит более миллиона URL. Мне нужно обработать этот файл, чтобы назначить URL-адреса группам на основе адреса хоста:

{
    'http://www.ex1.com' => ['http://www.ex1.com/...', 'http://www.ex1.com/...', ...],
    'http://www.ex2.com' => ['http://www.ex2.com/...', 'http://www.ex2.com/...', ...]
}

Моему текущему базовому решению для этого требуется около 600 МБ ОЗУ (размер файла около 300 МБ). Не могли бы вы предоставить более эффективные способы?

Мое текущее решение просто читает строку за строкой, извлекает адрес хоста посредством регулярного выражения и помещает URL в хеш.

EDIT

Вот моя реализация (я обрезал ненужные вещи):

while($line = <STDIN>) { 
    chomp($line); 
    $line =~ /(http:\/\/.+?)(\/|$)/i; 
    $host = "$1"; 
    push @{$urls{$host}}, $line; 
}

store \%urls, 'out.hash'; 

Ответы [ 4 ]

5 голосов
/ 07 апреля 2010

Один из подходов, который вы можете использовать, - это привязать ваш URL-хэш к СУБД, например BerkeleyDB . Вы можете явно указать опции, сколько памяти он может использовать.

1 голос
/ 07 апреля 2010

Помимо сохранения ваших структур данных на диске (связанный хэш DBM, как предложил Леон Тиммерманс, база данных SQL, такая как SQLite3 и т. Д.), Вы не сможете значительно сократить потребление памяти.300M реальных данных, плюс интерпретатор perl, представление байт-кода вашей программы, плюс метаданные в каждой из извлеченных строк увеличат общее количество используемой памяти до 300M, если вы сохраните все это в памяти.Во всяком случае, я слегка удивлен, что он только вдвое больше размера входного файла.

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

1 голос
/ 07 апреля 2010

Если вы читаете 600 МБ из двух файлов и сохраняете их в памяти (в хэше), у вас мало места для оптимизации с точки зрения использования памяти (если не считать сжатие данных, что, вероятно, не является жизнеспособным вариантом).

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

EDIT:

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

0 голосов
/ 13 апреля 2010

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

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