Board logo

标题: [技术讨论] [Perl]超大哈希表(超过1G的那种)的存取 [打印本页]

作者: 523066680    时间: 2018-9-22 11:56     标题: [Perl]超大哈希表(超过1G的那种)的存取

本帖最后由 523066680 于 2018-9-22 12:01 编辑

在CU遇到几次超大哈希的处理问题。这边也分享一下。
通过使用 DB_File 模块,可以将哈希数据存取操作转为在磁盘文件中处理,避免爆内存。

写入示例:
  1. use DB_File;
  2. STDOUT->autoflush(1);
  3. my $DBFile = "F:/temp.db";
  4. unlink $DBFile if ( -e $DBFile );
  5. my %h;
  6. tie %h, "DB_File", $DBFile, O_WRONLY|O_CREAT, 0666, $DB_BTREE or die "$!" ;
  7. # Make many useless hash key/value
  8. my $max = 1000_0000;
  9. my ($iter, $curr, $prev) = (0, 0, 0);
  10. while ($iter++ < $max)
  11. {
  12.     $h{ $iter } = join("", map { ('a'..'z')[rand(26)] } (0 .. int(rand(60)+1) ) );
  13.     $curr = $iter / $max * 100.0;
  14.     if ( ($curr - $prev) >= 1.0)
  15.     {
  16.         printf "%.1f\% ", $curr;
  17.         $prev = $curr;
  18.     }
  19. }
  20. untie %h;
  21. print "Done\n";
复制代码
由于时间长,加了一些进度显示的代码。
实际过程非常简单,创建数据库文件 -> tie 绑定数据库和哈希表名称 -> 像常规操作哈希表一样存取 -> untie %h 结束操作并保留结果。

读取示例:
  1. use DB_File;
  2. my $DBFile = "F:/temp.db";
  3. my %h;
  4. tie %h, "DB_File", $DBFile, O_RDONLY, 0666, $DB_BTREE or die "$!" ;
  5. print $h{"100021"};
  6. untie %h ;
复制代码

作者: Wiki    时间: 2018-9-23 00:08

避免爆内存。





欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2