免费注册 查看新帖 |

Chinaunix

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

对文件(列表)的查询及效率问题,请各位讨论下(暂时解决) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-06-15 19:27 |显示全部楼层 |倒序浏览
1.pl:

#!/usr/bin/perl -w

use strict;
use POSIX qw(strftime);

my $t1=strftime "%Y%m%d%H%H%S",localtime;
my $date=strftime "%Y%m%d",localtime;
my $log="/log${date}0000.dat";
chomp (my $ok=`/bin/grep 'Login OK' $log | wc -l`);
my $incorrect=`/bin/grep 'Login incorrect' $log | wc -l`;
open FILE,"> /log/radius_tongji.log" or die "$!";
print FILE $date . "\t" . $ok . "\t" . $incorrect;
close FILE;
my $t2=strftime "%Y%m%d%H%H%S",localtime;
print $t2-$t1 . "\n";



2.pl:
#!/usr/bin/perl -w

use strict;
use POSIX qw(strftime);

my ($ok,$incorrect);
my $t1=strftime "%Y%m%d%H%H%S",localtime;
my $date=strftime "%Y%m%d",localtime;
my $log="/log${date}0000.dat";
open FILE,"< $log" or die "$!";
while (<FILE>)
{
        $ok++ if /Login OK/i;
        $incorrect++ if /Login incorrect/i;
}
close FILE;
open FILE2,">> /log/radius_tongji.log" or die "$!";
print FILE2 $date . "\t" . $ok . "\t" . $incorrect . "\n";
close FILE2;
my $t2=strftime "%Y%m%d%H%H%S",localtime;
print $t2-$t1 . "\n";


运行1.pl花了13秒,运行2.pl花了22秒。
但感觉1.pl嵌套了shell效率不是很高,而2.pl是纯的perl语句,但效率不如1.pl.

请教各位,选择哪个呢?还有其他更好的办法吗?

[ 本帖最后由 gaochong 于 2009-6-16 16:49 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-06-15 21:10 |显示全部楼层

回复 #2 MMMIX 的帖子

去掉 //i 中的i,效率是高了,但相比1.pl还是慢了1秒。 谢谢!

日志文件一般在500M到5G之间,我该选1.pl还是2.pl呢?或者有其他更好的code吗?

论坛徽章:
0
3 [报告]
发表于 2009-06-15 22:28 |显示全部楼层

回复 #4 MMMIX 的帖子

我试了一个846M的文件,跑1.pl花了29秒,跑2.pl花了30秒,而且2.pl的负载相对更高。不知道3G\4G的文件会怎样,明天试试看。

但遇到一个问题:怎么会跑出下边的结果呢?应该是$t2>$t1才对。怎么是这样了呢?

-bash-3.00$ ./2.pl
20090615222242
20090615222212
-30

论坛徽章:
0
4 [报告]
发表于 2009-06-15 22:42 |显示全部楼层
原帖由 yecheng_110 于 2009-6-15 22:19 发表

赞同 如果一行不可能同时有Login incorrect和Login OK
那么LZ做了多余的比较


日志文件中,一行不可能同时又OK和incorrect。但我是要统计OK和incorrect的行数,所以不是多余的比较。

为什么要加next ???没明白2位的意思。

论坛徽章:
0
5 [报告]
发表于 2009-06-15 23:32 |显示全部楼层

回复 #10 MMMIX 的帖子

哎呀,晕了。非常明白了,谢谢2位!


但实际跑了一下,加和不加,都跑了30秒。从代码上分析,应该是加next会节省时间但结果却没有。

论坛徽章:
0
6 [报告]
发表于 2009-06-16 09:15 |显示全部楼层

回复 #12 MMMIX 的帖子

谢谢了!

成功和失败的数量:20090527        293163  3319309

Login incorrect匹配的多,但效率还是一样,也是用了30秒。

while (<FILE>)
{
        if (/Login incorrect/) {
                $incorrect++;
                next;
        }
        $ok++ if /Login OK/;
}

论坛徽章:
0
7 [报告]
发表于 2009-06-16 10:34 |显示全部楼层

回复 #14 yashiro_lj 的帖子

谢谢,但不是只有这2个可能。

我的日志格式如下:
Thu Jan 15 10:02:10 2009 : Auth: Login incorrect: [ac/d] (from client)
Thu Jan 15 10:02:12 2009 : Error: Username [ac] Reject Message
Thu Jan 15 10:02:12 2009 : Auth: Login incorrect: [ac/b] (from client)
Thu Jan 15 10:02:15 2009 : Auth: Login OK: [ab/c] (from client)

论坛徽章:
0
8 [报告]
发表于 2009-06-16 10:41 |显示全部楼层

回复 #15 gaochong 的帖子

为了寻求可能更高的效率,我想到了grep,写了3.pl如下:

#!/usr/bin/perl -w

use strict;
use POSIX qw(strftime);

my $t1=strftime "%Y%m%d%H%H%S",localtime;
print "$t1\n";
#my $date=strftime "%Y%m%d",localtime;
my $date=20090527;
my $log="/logs/log${date}0000.dat";
open FILE,"< $log" or die "$!";
my @list=grep /Login OK/,<FILE>;
close FILE;
open FILE_t,"< $log" or die "$!";
my @list2=grep /Login incorrect/,<FILE_t>;
close FILE_t;
open FILE2,">> /export/home/gaochong/radius_tongji.log" or die "$!";
print FILE2 $date . "\t" . scalar @list . "\t" . scalar @list2 . "\n";
close FILE2;
my $t2=strftime "%Y%m%d%H%H%S",localtime;
print "$t2\n";
print $t2-$t1 . "\n";



从程序上分析,I/O次数多了一次,效率可能会更低。
但我运行./3.pl ,却好像僵死一样,跑了1分钟还没有结果。

是因为I/0的问题吗?

论坛徽章:
0
9 [报告]
发表于 2009-06-16 10:50 |显示全部楼层

回复 #16 yashiro_lj 的帖子

是的。

我用如下代码,却跑了38秒!!!比原来的30秒效率更低了。
while (<FILE>)
{
        if (/\bincorrect\b/) {
                $incorrect++;
                next;
        }
        $ok++ if /\bOK\b/;
}

去掉锚点,花了29秒,和之前的code效率基本持平。但去掉锚点可能会有偏差,比如有 abOKc.

自己的结论:锚点降低了查询效率。  请各位指正。

论坛徽章:
0
10 [报告]
发表于 2009-06-16 10:54 |显示全部楼层
原帖由 yashiro_lj 于 2009-6-16 10:48 发表
你这样写就等于循环了2次(一次用于检查incorrect,一次用于检查OK),效率上估计还比不上只while循环一次呢。

my @list=grep /Login OK/,;
这样写会把整个当做一个列表一次性都读入内存的,如果文件过大, ...






my @list=grep /Login OK/,<FILE>;

这个还是太危险了。我想也是我终于的新手最容易犯的错误。

记住了,用while最保险!  foreach 和 以上代码要切忌!!

谢谢!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP