免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: glauke
打印 上一主题 下一主题

如何控制perl程序的内存? [复制链接]

论坛徽章:
0
31 [报告]
发表于 2010-05-14 13:06 |只看该作者
{:3_188:}哈哈   我们都入了误区了。为何一定要一个字符一个字符读入呢?
就PERL的处理机制而言,这样每读入一个字符,就肯定要占用大于一个字符的存储空间。

不过要实现楼主的需求,可以用另外一个方法。

代码入下,楼主可以试试效率哈~

  1. $/='';

  2. $a=<>;
  3. $b = substr($a,131783200,1);
  4. print $b;
复制代码

论坛徽章:
0
32 [报告]
发表于 2010-05-14 13:08 |只看该作者
回复 30# ttcn_cu


    我觉得 lz的5G内存  中间的3G是要处理的文件   剩下的那2G是另外一个拿来验证的文件   所以这样建一个哈希 绝对会耗更多的内存

论坛徽章:
1
狮子座
日期:2013-12-16 16:09:24
33 [报告]
发表于 2010-05-14 13:13 |只看该作者
回复 32# guap514


如果真有那么大的标准数据量的话,那就不应该用哈希
而是把标准数据先排序,再在循环中动态的加载,比较.

论坛徽章:
0
34 [报告]
发表于 2010-05-14 13:29 |只看该作者
回复 31# toniz


这个方法我之前想到过,问题是如果检测位点比较多的话,substr的速度会远远慢于查表的速度。

当然这个肯定也能解决这个小问题,虽然时间慢点,内存肯定很小。

我现在只是由这个小问题想去研究下perl的存储而已,如何实现低内存的建表,或者说如何使数组的内存所耗不要过大。

论坛徽章:
0
35 [报告]
发表于 2010-05-14 13:32 |只看该作者
回复 32# guap514

不是这样的,我现在所做的测试都是只做了一件事情,就是读取正确文件然后存到数组里。

比如:

$/ = \1;
my @a;
while (<>){
         push @a, $_;
}

就这样的一小部分代码读60M的文件耗内存为5G。

论坛徽章:
0
36 [报告]
发表于 2010-05-14 13:34 |只看该作者
回复 25# glauke


没问题的, 你要的不就是个验证么。 以每次处理5M 为例.

  1. my $batch = 5 * 1024 * 1024;
  2. my $start = 1;
  3. my $end   = $start + $batch;
  4. my @charsToBeChecked = ();
  5. open my $code, "<b";
  6. while (<>) {
  7.     push @charsToBeChecked, split //, $_;
  8.     if ( @charsToBeChecked > $batch ) {
  9.         while (<$code>) {
  10.             chomp;
  11.             m/(\d+)\s*(\w)/;
  12.             my $pos  = $1 - $start;
  13.             my $char = $2;
  14.             next unless ( $pos < $batch and $pos >= 0 );
  15.             if ( $charsToBeChecked[$pos] ne $char ) {
  16.                 printf STDERR "pos: %d, expected: %s actual: %s\n", $pos,
  17.                     $char, $charsToBeChecked[$pos];
  18.             }
  19.         }
  20.         $start            = $end + 1;
  21.         $end              = $start + $end;
  22.         @charsToBeChecked = ();
  23.     }
  24. }
  25. while (<$code>) {
  26.     chomp;
  27.     m/(\d+)\s*(\w)/;
  28.     my $pos  = $1 - $start;
  29.     my $char = $2;
  30.     next unless ( $pos < $batch and $pos >= 0 );
  31.     if ( $charsToBeChecked[$pos] ne $char ) {
  32.         printf STDERR "pos: %d, expected: %s actual: %s\n", $pos, $char,
  33.             $charsToBeChecked[$pos];
  34.     }
  35. }
复制代码
还可以先对校验文件做下预处理, 把它分成许多小文件 这样可以避免反复读去校验文件

论坛徽章:
0
37 [报告]
发表于 2010-05-14 13:36 |只看该作者
对了 没有问清楚
你的校验文件大么。 不大的话先把校验文件读到内存中排序。
然后再对原文件中的字符依次处理就成了 也不用放到数组里。

论坛徽章:
0
38 [报告]
发表于 2010-05-14 13:36 |只看该作者
回复 35# glauke


    如果perl的内存控制这么垃圾的话   也就没有那么多人用了  呵呵
反正我是肯定没有遇到这样的问题

论坛徽章:
0
39 [报告]
发表于 2010-05-14 13:54 |只看该作者
回复 37# DQP

多谢大侠热心的回复!

校验文件比较大,因为不仅包括这两个信息,还有一些其他的信息。当然我们可以只把这两项信息存到内存里,但是如何存呢,最好还是用hash吧我想,

可是这样的话内存会耗多大我就不知道了,我可以有时间做下测试哈,到时候把结果告你。

你前面的那个分块的程序我看了,我明白你的思想,但是这其实和substr一样是一个拿时间换空间的办法,因为你分了多少块就要扫几次校验文件,如果校验文件

比较大就不大可行了。

论坛徽章:
0
40 [报告]
发表于 2010-05-14 13:57 |只看该作者
回复 39# glauke


可以先把校验文件分块 就不用扫描多次了。
排序后的校验文件当然是放数组里了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP