免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
51 [报告]
发表于 2010-05-14 15:03 |只看该作者
我测了 真的这么大。。。。
也许从思路上就错了 根本不该那么做的。

论坛徽章:
0
52 [报告]
发表于 2010-05-14 15:10 |只看该作者
我测了 真的这么大。。。。
也许从思路上就错了 根本不该那么做的。
DQP 发表于 2010-05-14 15:03



    O_o
不会是也像lz那样把60M的文件 都分割成数组吧

论坛徽章:
0
53 [报告]
发表于 2010-05-14 15:12 |只看该作者
回复 50# guap514


    好吧  楼主很懒  我只能做苦力了。

用这个代码创建一个校验文件。命令行是:perl b.pl t.t  >cd.log
t.t是:-rw-rw-r-- 1 etl  etl     320843 May 14 14:46 t.t
  1. $/=\1;
  2. my $i=1;
  3. while(<>){
  4. print $_."   ".$i++ ."\n";
  5. }
复制代码
运行之后得到一个校验文件:cd.log。  这是我懒得去弄,就直接全字符检验了。这个检验文件够大了吧,。

好吧,下面的代码开始测试:
  1. use Time::HiRes qw(gettimeofday);
  2. my ($start_sec, $start_usec) = gettimeofday;

  3. use Data::Dumper;
  4. $o=$/;
  5. $/=\1;
  6. @a=<>;
  7. open F,"cd.log" or die "asdfasf";
  8. $/=$o;
  9. while(<F>){
  10.                 @b=split /\s+/,$_;
  11.                 if($a[$b[1]-1] != $b[0] ){
  12.                         print "$b[0]  $b[1]  not eq \n";
  13.                 }       
  14. }

  15. my ($end_sec, $end_usec) = gettimeofday;
  16. my $time_used = ($end_sec - $start_sec) + ($end_usec - $start_usec)/1000000;
  17. printf("time used  : %.10f\n", $time_used);
复制代码
这个是测试楼组的用数组下标检索判断的。消耗时间如下:
  1. [etl@dmtest bidm]$ perl b.pl t.t
  2. time used  : 1.1311360000
复制代码
之后是substr的。
  1. use Time::HiRes qw(gettimeofday);
  2. my ($start_sec, $start_usec) = gettimeofday;
  3. $o=$/;
  4. $/='';
  5. $a=<>;
  6. open F,"cd.log" or die "asdfasf";
  7. $/=$o;
  8. while(<F>){
  9.         @b=split /\s+/,$_;
  10.         if(substr($a,$b[1]-1,1) != $b[0] ){
  11.                                 print "$b[0]  $b[1]  ".substr($a,$b[1],1)."  not eq \n";
  12.         }
  13. }

  14. my ($end_sec, $end_usec) = gettimeofday;
  15. my $time_used = ($end_sec - $start_sec) + ($end_usec - $start_usec)/1000000;
  16. printf("time used  : %.10f\n", $time_used);
复制代码
消耗时间是:
  1. [etl@dmtest bidm]$ perl b.pl t.t
  2. time used  : 0.8436160000
复制代码
所以说,是选错的方法,不是perl不行。。。。

论坛徽章:
0
54 [报告]
发表于 2010-05-14 15:12 |只看该作者
我还真这么干了。。。 刚开始是不知道他想要什么
p.s.我的100M 的. 增长到4G 时就out of memory了。。。

论坛徽章:
0
55 [报告]
发表于 2010-05-14 18:05 |只看该作者
回复 53# toniz


好人啊!感激涕零!太谢谢啦!

你的热心鼓舞了我又做了测试,的确是substr很快,但我想主要是快在不用split存数组那儿吧,至于查找的速度按下标还是substr是应该差不多的。

另外你的程序有几点还有待优化啊:

你做的存数组的那个测试,直接@a = <>会比while(<>){push @a, $_;}耗的内存要大很多。

至于substr那个测试,应该加上一句s/\n//g把\n去掉,不然结果会不对的。

总之谢谢大侠的热心帮助拉!

论坛徽章:
0
56 [报告]
发表于 2010-05-16 19:08 |只看该作者
学习了

论坛徽章:
0
57 [报告]
发表于 2010-05-16 22:58 |只看该作者
你可以每读一段,就分割、处理、放入内存。 这样效率比较高。

用ps u -C <test.pl> 来监控你的程序内存使用情况。

论坛徽章:
0
58 [报告]
发表于 2010-05-17 09:23 |只看该作者
本帖最后由 toniz 于 2010-05-17 09:51 编辑

回复 55# glauke


    我就随手写的测试脚本,你居然还挑我错误 呜。。。。

不过想想还是解释下哈:

@a = <>我用这个是为了保证测试代码的结构和使用的方法一致。因为你注意没有?substr测试的时候,是把代码整个读入内存的。所以我需要在测试你那种数组下标的方法的时候,也一次读入内存。这样才公平~~

至于换行,呵呵,我的两个脚本把换行当一字符的,所以结果是不会不正确滴。。。当然,如果你自己弄的测试脚本一个算了,一个不算,那就糟糕~~


至于效率慢是慢在分配内存还是慢在下标检索,这个也是可以测试一下的~~

论坛徽章:
0
59 [报告]
发表于 2011-08-23 15:32 |只看该作者
回复  glauke


     我就随手写的测试脚本,你居然还挑我错误 呜。。。。

不过想想还是解释下 ...
toniz 发表于 2010-05-17 09:23



    toniz令人敬佩!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP