我正在开发一个涉及构建包含约1700万个键的哈希表的Perl项目。这对于存储在内存中来说太大了,我的笔记本电脑最多只能容纳约1000万个键。我知道解决方案是将数据存储到磁盘上,但是我在实践中遇到了困难。以下是我尝试过的:
DB_File
use strict;
use DB_File;
my $libfile = shift;
my %library;
tie %library, "DB_File", "$libfile";
for (my $a = 1; $a < 17000000; a++) {
# Some code to generate key and value #
$library{$key} = $value;
}
这个循环在执行到一半时出现了“segmentation fault: 11”的错误,原因我不清楚。
BerkeleyDB
use strict;
use BerkeleyDB;
my $libfile = shift;
my $library = new BerkeleyDB::Hash
-Filename => $libfile,
-Flags => DB_CREATE;
for (my $a = 1; $a < 17000000; a++) {
# Some code to generate key and value #
$library->db_put($key, $value);
}
这在处理大约1500万个键时似乎效果良好,但随后速度急剧下降,并最终在循环结束前完全停止响应。我认为这不是内存问题;如果将循环分成四段,将它们放入四个单独的程序中并依次运行它们(每次向数据库添加~400万个记录),前三个程序能够成功完成,但当数据库有约1500万个键时第四个程序会挂起。因此看起来BerkeleyDB可能只能处理约1500万个哈希键吗?
DBM::Deep
use strict;
use DBM::Deep;
my $libfile = shift;
my $library = new DBM::Deep $libfile;
for (my $a = 1; $a < 17000000; a++) {
# Some code to generate key and value #
$library->put($key => $value);
}
初步测试似乎可以正常工作,但速度非常慢:每千个密钥需要大约5秒钟,或者运行整个循环需要约22小时。如果有可能的话,我宁愿避免这种情况。
如果您对排除这些包之一的故障有建议,或者有关实现相同功能的其他选项的想法,我将非常感谢。
更新