perl中非常庞大的assosiative数组

前端之家收集整理的这篇文章主要介绍了perl中非常庞大的assosiative数组前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要将两个文件合并到一个新文件中.

两者有超过300百万个以管道分隔的记录,第一列为主键.行未排序.第二个文件可能有第一个文件没有的记录.

示例文件1:

  1. 1001234|X15X1211,J,S,12,15,100.05

示例文件2:

  1. 1231112|AJ32,18,JP
  2. 1001234|AJ15,16,PP

输出

  1. 1001234,X15X1211,100.05,AJ15,PP

我正在使用以下代码

  1. tie %hash_REP,'Tie::File::AsHash','rep.in',split => '\|'
  2. my $counter=0;
  3. while (($key,$val) = each %hash_REP) {
  4. if($counter==0) {
  5. print strftime "%a %b %e %H:%M:%S %Y",localtime;
  6. }
  7. }

准备关联数组需要将近1个小时.
这真的很好还是真的很糟糕?
有没有更快的方法来处理关联数组中的这种大小的记录?
任何脚本语言的任何建议都会有所帮助.

谢谢,
尼丁T.

我也尝试过以下程序,walso花了1小时如下:

  1. #!/usr/bin/perl
  2. use POSIX qw(strftime);
  3. my $now_string = strftime "%a %b %e %H:%M:%S %Y",localtime;
  4. print $now_string . "\n";
  5.  
  6. my %hash;
  7. open FILE,"APP.in" or die $!;
  8. while (my $line = <FILE>) {
  9. chomp($line);
  10. my($key,$val) = split /\|/,$line;
  11. $hash{$key} = $val;
  12. }
  13. close FILE;
  14.  
  15. my $filename = 'report.txt';
  16. open(my $fh,'>',$filename) or die "Could not open file '$filename' $!";
  17. open FILE,"rep.in" or die $!;
  18. while (my $line = <FILE>) {
  19. chomp($line);
  20. my @words = split /\|/,$line;
  21. for (my $i=0; $i <= $#words; $i++) {
  22. if($i == 0)
  23. {
  24. next;
  25. }
  26. print $fh $words[$i] . "|^"
  27. }
  28. print $fh $hash{$words[0]} . "\n";
  29. }
  30. close FILE;
  31. close $fh;
  32. print "done\n";
  33.  
  34. my $now_string = strftime "%a %b %e %H:%M:%S %Y",localtime;
  35. print $now_string . "\n";

解决方法

由于一些原因,您的技术效率极低.

>搭售非常缓慢.
>你把一切都拉进记忆中.

第一个可以通过自己阅读和分裂来缓解,但后者总是会成为一个问题.经验法则是避免将大量数据存入内存.它会占用所有内存并可能导致它交换到磁盘并减慢waaaay,特别是如果你使用旋转磁盘.

相反,您可以使用各种“磁盘哈希”来使用GDBM_FileBerkleyDB等模块.

但是真的没有理由搞乱他们因为我们有sqlite而且它做的更快更好.

sqlite中创建一个表.

  1. create table imported (
  2. id integer,value text
  3. );

使用sqlite shell的.import导入文件,使用.mode和.separator调整格式.

  1. sqlite> create table imported (
  2. ...> id integer,...> value text
  3. ...> );
  4. sqlite> .mode list
  5. sqlite> .separator |
  6. sqlite> .import test.data imported
  7. sqlite> .mode column
  8. sqlite> select * from imported;
  9. 12345 NITIN
  10. 12346 NITINfoo
  11. 2398 bar
  12. 9823 baz

现在,您和其他任何必须使用数据的人都可以使用高效,灵活的sql做任何您喜欢的事情.即使导入需要一段时间,你也可以去做其他事情.

猜你在找的Perl相关文章