免费注册 查看新帖 |

Chinaunix

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

perl脚本占用资源比较大,怎么找原因呢? [复制链接]

论坛徽章:
0
11 [报告]
发表于 2010-05-07 10:41 |只看该作者
{:3_198:}  正则尽量少,可以尝试改成这样:
  1. \s+(http:\/\/.+?)\s+
复制代码
代码运行时,用free -m,看交换区使用情况,如果交换区耗光,则应该是哈希太大。可以考虑分几次写入文件。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
12 [报告]
发表于 2010-05-07 14:25 |只看该作者
推荐楼主用Devel::NYTProf

论坛徽章:
0
13 [报告]
发表于 2010-05-08 17:14 |只看该作者
我问个题外话,你的日志是tcpdump生成的么?多大个,怎样生成的,用了多少时间?

我也想处理我的日志,就是tcpdump -w日志,想导出为txt,但是太浪费时间了,200M+需要大概2.5小时。

有什么好办法么?

论坛徽章:
1
狮子座
日期:2013-11-13 22:28:35
14 [报告]
发表于 2010-05-09 00:32 |只看该作者
正则尽量少,可以尝试改成这样:代码运行时,用free -m,看交换区使用情况,如果交换区耗光,则应 ...
toniz 发表于 2010-05-07 10:41



    怎样的正则才是性能比较好的呢?
   这个问题我也问过提供这个脚本的同事,他的回答是匹配度越高越好。

论坛徽章:
0
15 [报告]
发表于 2010-05-09 09:24 |只看该作者
回复 6# Osment

没有oi,但是人家有qr。

并且,i跟你说的性能上不仅仅没有优化,理论上应该更慢。i是ignore case sensitiive。
o才是只编译正则一次。

论坛徽章:
0
16 [报告]
发表于 2010-05-09 09:38 |只看该作者
  1. 1273144492.670      9 121.14.225.183 TCP_IMS_HIT/304 236 GET http://www.ggv.com.cn/downfiles/20070815_135941_1.rar  - NONE/- text/plain "http://down.ggv.com.cn/down/cnt_n_down.php?id=698400&flag=1" "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"
  2. 脚本里相关部分是:
  3. my $log_pattern   = qr '^.*?\d+\s+\w+\s+(http:\/\/.+?)\s+.+';
复制代码
没有什么想不明白的。正则表达式只是为了写得尽可能准确。越准确正则引擎需要做的猜测类工作越少,性能相对越好。
正则分解如下:
/
^.*? # 前面那些
\d+  # 上面的236
\s+  # 空白
\w+  # GET
\s+  # 空白
(http:\/\/.+?) # url
\s+ # 空白
.+  # 后面剩余的
/
这个正则不一定非要这样写,但目的只有两个:
1. 能够匹配,这是做这件事的根本目的,
2. 严谨,如果使用split速度肯定更快,但是如果日志里有不完整或者残缺或者不准确的日志的话,split将出问题,而且直接使用split (//, @list)[7]可能会被perl报一个uninitialized value的错误信息;
3. 正则写的相对完整,完整意味着“描述上没有含糊不清,更精确”,体现了2的严谨,也能提高速度。否则直接写个:
^.*?http:\/\/.+\s+.+就能匹配出来了,但速度上你可以测试下。

但是这个正则前面的.*?可以进行进一步优化。因为这样正则引擎在匹配的时候可能需要做的步骤是:
因为加了非贪婪的?,首先匹配:
将.*?当成空白跟后面的正则加在一起,看能否匹配成功,如果匹配失败,则:
将.*?当成一个字符,进行匹配,如果匹配失败,则:
再向右读取一个字符再匹配,循环,一直到匹配成功为止。

论坛徽章:
1
狮子座
日期:2013-11-13 22:28:35
17 [报告]
发表于 2010-05-09 10:57 |只看该作者
没有什么想不明白的。正则表达式只是为了写得尽可能准确。越准确正则引擎需要做的猜测类工作越少,性能相对 ...
yigenjin 发表于 2010-05-09 09:38



    向右读取?


我用楼上说的nytporf测了一下,原先的正则30us/call,改成\s(http:\/\/.+?)\s后7us/call。

论坛徽章:
1
狮子座
日期:2013-11-13 22:28:35
18 [报告]
发表于 2010-05-09 11:00 |只看该作者
向右读取的意思是不是说从尽可能少的字符匹配开始,直到凑够了“1273144492.670      9 121.14.225.183 TCP_IMS_HIT/304 ”这一串?

论坛徽章:
0
19 [报告]
发表于 2010-05-09 18:46 |只看该作者
while <FH> 是个比较偷懒  效率不高的方法   尤其对大文件  
是否可以对数据先处理下呢  把没有的字段去掉      用mem resouce 代替cpu resource  
就看你时间和空间的取舍了     
也可以split big file  或 multi thread 来做

论坛徽章:
0
20 [报告]
发表于 2010-05-10 11:06 |只看该作者
回复 17# chenryn


    {:3_190:} 在同样能够精确匹配的情况下,自然是越短越快啊。。。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP