免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 21176 | 回复: 14
打印 上一主题 下一主题

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

论坛徽章:
0
1 [报告]
发表于 2010-05-13 17:34 |显示全部楼层
上代码

论坛徽章:
0
2 [报告]
发表于 2010-05-13 18:02 |显示全部楼层
回复 4# glauke


    那个$a看上去没有什么意义.  还不确定占用内存大是否和反复拼接字符串有关, 去掉试验下.

  1. my @foo;
  2. while(<>){
  3.   chomp;
  4.   push @foo, split //, $_;
  5. }
复制代码

论坛徽章:
0
3 [报告]
发表于 2010-05-13 18:43 |显示全部楼层
本帖最后由 DQP 于 2010-05-13 19:38 编辑

他又没说他想干嘛
至少省下个字符串。 而且一次对这么大个字符串做splite估计会生成很大的中间变量。

论坛徽章:
0
4 [报告]
发表于 2010-05-13 19:39 |显示全部楼层
你要干啥?

论坛徽章:
0
5 [报告]
发表于 2010-05-13 19:56 |显示全部楼层
没有。
如果你一定要把每个字符都放到数组中去。 那么没办法帮你。
你把你的需求说出来 也许能想出其他办法

论坛徽章:
0
6 [报告]
发表于 2010-05-14 10:37 |显示全部楼层
回复 20# glauke


这样啊。  可以分成块做。 每次只读一定数量的字符(比如1M)然后对这块进行验证。
如果这是一个独立的需求 拿C写算了。 多不了几行。。

论坛徽章:
0
7 [报告]
发表于 2010-05-14 10:42 |显示全部楼层
另外前面有位哥们说把换行符换成空,然后再读,我发现这样写不是一个字符一个字符的读,而是直接读到了文件的末尾,好奇怪啊,这是为什么呢?

当$/为undef或空的话就会把整个文件当作一行

论坛徽章:
0
8 [报告]
发表于 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
9 [报告]
发表于 2010-05-14 13:36 |显示全部楼层
对了 没有问清楚
你的校验文件大么。 不大的话先把校验文件读到内存中排序。
然后再对原文件中的字符依次处理就成了 也不用放到数组里。

论坛徽章:
0
10 [报告]
发表于 2010-05-14 13:57 |显示全部楼层
回复 39# glauke


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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP