本帖最后由 523066680 于 2018-9-22 12:01 编辑
在CU遇到几次超大哈希的处理问题。这边也分享一下。
通过使用 DB_File 模块,可以将哈希数据存取操作转为在磁盘文件中处理,避免爆内存。
写入示例: | use DB_File; | | STDOUT->autoflush(1); | | | | my $DBFile = "F:/temp.db"; | | unlink $DBFile if ( -e $DBFile ); | | | | my %h; | | tie %h, "DB_File", $DBFile, O_WRONLY|O_CREAT, 0666, $DB_BTREE or die "$!" ; | | | | | | my $max = 1000_0000; | | my ($iter, $curr, $prev) = (0, 0, 0); | | | | while ($iter++ < $max) | | { | | $h{ $iter } = join("", map { ('a'..'z')[rand(26)] } (0 .. int(rand(60)+1) ) ); | | | | $curr = $iter / $max * 100.0; | | if ( ($curr - $prev) >= 1.0) | | { | | printf "%.1f\% ", $curr; | | $prev = $curr; | | } | | } | | | | untie %h; | | print "Done\n";COPY |
由于时间长,加了一些进度显示的代码。
实际过程非常简单,创建数据库文件 -> tie 绑定数据库和哈希表名称 -> 像常规操作哈希表一样存取 -> untie %h 结束操作并保留结果。
读取示例: | use DB_File; | | my $DBFile = "F:/temp.db"; | | my %h; | | tie %h, "DB_File", $DBFile, O_RDONLY, 0666, $DB_BTREE or die "$!" ; | | print $h{"100021"}; | | untie %h ;COPY |
|