在Perl中快速查找:可以重新加载哈希值吗?

时间:2012-02-22 18:21:39

标签: perl hash

我有大约1亿行,例如:

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

目前,每次运行程序时,我都会将整个文件作为哈希加载,这需要一些时间。在运行期间,我需要访问A,B的值,因为我知道A,B等。

我想知道我是否可以进行一次哈希并将其存储为二进制数据结构或索引文件。使用最少的编程可以在perl中实现什么。

谢谢! -Abhi

3 个答案:

答案 0 :(得分:9)

我建议使用磁盘上的键/值数据库。由于Perl的tie function,它们可以与正常的内存中哈希相同地使用。如果哈希非常大,它们将比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 ......)

答案 1 :(得分:7)

看看Storable - 它应该做你想做的事情并且使用起来非常简单:

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

当然,如果您的程序实际上受CPU速度限制,这只会有所帮助。由于您的数据结构非常简单,因此您可能比从磁盘读取数据结构更快地解析它。在这种情况下,Storable不会帮助你。

答案 2 :(得分:1)

我建议使用Tie::File,因为它包含在内核中,并且不会将整个数据结构加载到内存中,而是根据需要从磁盘访问单个记录。