очень быстрый поиск в Perl: возможна ли повторная загрузка хеш-значений? - PullRequest
4 голосов
/ 22 февраля 2012

У меня есть около 100 миллионов строк, таких как:

A : value of A
B : value of B
|
|
|
Z : value of Z  upto 100 million unique entries

В настоящее время каждый раз, когда я запускаю свою программу, я загружаю весь файл как хеш, который занимает некоторое время. Во время выполнения мне нужен доступ к значению A, B, если я знаю A, B и т. Д.

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

Спасибо! -Abhi

Ответы [ 3 ]

9 голосов
/ 22 февраля 2012

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

BerkeleyDB - старый фаворит:

use BerkeleyDB;
# Make %db an on-disk database stored in database.dbm. Create file if needed
tie my %db, 'BerkeleyDB::Hash', -Filename => "database.dbm", -Flags => DB_CREATE
    or die "Couldn't tie database: $BerkeleyDB::Error";

$db{foo} = 1;            # get value
print $db{foo}, "\n";    # set value
for my $key (keys %db) {
    print "$key -> $db{$key}\n";  # iterate values
}

%db = ();  # wipe

Изменения в базе данных автоматически сохраняются на диск и сохраняются при многократном вызове вашего скрипта.

Проверьте параметры в perldoc, но наиболее важными являются:

# Increase memory allocation for database (increases performance), e.g. 640 MB
tie my %db, 'BerkeleyDB::Hash', -Filename => $filename, -CacheSize => 640*1024*1024;

# Open database in readonly mode
tie my %db, 'BerkeleyDB::Hash', -Filename => $filename, -Flags => DB_RDONLY;

Более сложной, но гораздо более быстрой библиотекой базы данных будет Tokyo Cabinet , и, конечно, есть много других опций (в конце концов, это Perl ...)

7 голосов
/ 22 февраля 2012

Посмотрите на Storable - он должен делать то, что вы хотите, и чрезвычайно прост в использовании:

use Storable;
store \%table, 'file';
$hashref = retrieve('file');

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

1 голос
/ 22 февраля 2012

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

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