这两条perl命令行怎么效率会差那么多?

这两条perl命令行怎么效率会差那么多?



[Copy to clipboard] [ - ]
CODE:
如果我想用第一种方式应该怎么改。
[root@localhost ~]# time perl -ne 'print if/9AB47623C28|8AE7B4482E2|454B844811E/' /var/log/maillog

Oct 12 08:30:02 localhost postfix/pickup[4323]: 9AB47623C28: uid=0 from=<root>
Oct 12 08:30:02 localhost postfix/cleanup[4483]: 9AB47623C28: message-id=<[email]20081012003002.9AB47623C28@localhost.com[/email]>
Oct 12 08:30:02 localhost postfix/qmgr[31024]: 9AB47623C28: from=<[email]root@localhost.com[/email]>, size=7723, nrcpt=1 (queue active)
Oct 12 08:30:04 localhost postfix/smtp[20996]: 9AB47623C28: to=<[email]sdfs@sci.com[/email]>, relay=mx.test.com[10.0.0.1]:25, delay=1.9, delays=0.14/0/0.13/1.6, dsn=2.0.0, status=sent (250 Ok: queued as 1F5A62CAA14)
Oct 12 08:30:04 localhost postfix/qmgr[31024]: 9AB47623C28: removed
Oct 13 08:30:02 localhost postfix/pickup[11374]: 8AE7B4482E2: uid=0 from=<root>
Oct 13 08:30:02 localhost postfix/cleanup[11967]: 8AE7B4482E2: message-id=<[email]20081013003002.8AE7B4482E2@localhost.com[/email]>
Oct 13 08:30:02 localhost postfix/qmgr[10207]: 8AE7B4482E2: from=<[email]root@localhost.com[/email]>, size=5238, nrcpt=1 (queue active)
Oct 13 08:30:10 localhost postfix/smtp[6866]: 8AE7B4482E2: to=<[email]sdfs@sci.com[/email]>, relay=mx.test.com[10.0.0.1]:25, delay=7.5, delays=0.11/0/0.13/7.3, dsn=2.0.0, status=sent (250 Ok: queued as 203FD2CAAEB)
Oct 13 08:30:10 localhost postfix/qmgr[10207]: 8AE7B4482E2: removed
Oct 14 08:30:02 localhost postfix/pickup[11662]: 454B844811E: uid=0 from=<root>
Oct 14 08:30:02 localhost postfix/cleanup[5763]: 454B844811E: message-id=<[email]20081014003002.454B844811E@localhost.com[/email]>
Oct 14 08:30:02 localhost postfix/qmgr[10207]: 454B844811E: from=<[email]root@localhost.com[/email]>, size=5205, nrcpt=1 (queue active)
Oct 14 08:30:03 localhost postfix/smtp[10233]: 454B844811E: to=<[email]sdfs@sci.com[/email]>, relay=mx.test.com[10.0.0.1]:25, delay=0.96, delays=0.22/0/0.13/0.61, dsn=2.0.0, status=sent (250 Ok: queued as D6D032CAAA6)
Oct 14 08:30:03 localhost postfix/qmgr[10207]: 454B844811E: removed

real    2m11.758s
user    1m30.065s
sys     0m1.000s


[root@localhost ~]# time perl -ne 'print if/9AB47623C28/||/8AE7B4482E2/||/454B844811E/' /var/log/maillog
Oct 12 08:30:02 localhost postfix/pickup[4323]: 9AB47623C28: uid=0 from=<root>
Oct 12 08:30:02 localhost postfix/cleanup[4483]: 9AB47623C28: message-id=<[email]20081012003002.9AB47623C28@localhost.com[/email]>
Oct 12 08:30:02 localhost postfix/qmgr[31024]: 9AB47623C28: from=<[email]root@localhost.com[/email]>, size=7723, nrcpt=1 (queue active)
Oct 12 08:30:04 localhost postfix/smtp[20996]: 9AB47623C28: to=<[email]sdfs@sci.com[/email]>, relay=mx.test.com[10.0.0.1]:25, delay=1.9, delays=0.14/0/0.13/1.6, dsn=2.0.0, status=sent (250 Ok: queued as 1F5A62CAA14)
Oct 12 08:30:04 localhost postfix/qmgr[31024]: 9AB47623C28: removed
Oct 13 08:30:02 localhost postfix/pickup[11374]: 8AE7B4482E2: uid=0 from=<root>
Oct 13 08:30:02 localhost postfix/cleanup[11967]: 8AE7B4482E2: message-id=<[email]20081013003002.8AE7B4482E2@localhost.com[/email]>
Oct 13 08:30:02 localhost postfix/qmgr[10207]: 8AE7B4482E2: from=<[email]root@localhost.com[/email]>, size=5238, nrcpt=1 (queue active)
Oct 13 08:30:10 localhost postfix/smtp[6866]: 8AE7B4482E2: to=<[email]sdfs@sci.com[/email]>, relay=mx.test.com[10.0.0.1]:25, delay=7.5, delays=0.11/0/0.13/7.3, dsn=2.0.0, status=sent (250 Ok: queued as 203FD2CAAEB)
Oct 13 08:30:10 localhost postfix/qmgr[10207]: 8AE7B4482E2: removed
Oct 14 08:30:02 localhost postfix/pickup[11662]: 454B844811E: uid=0 from=<root>
Oct 14 08:30:02 localhost postfix/cleanup[5763]: 454B844811E: message-id=<[email]20081014003002.454B844811E@localhost.com[/email]>
Oct 14 08:30:02 localhost postfix/qmgr[10207]: 454B844811E: from=<[email]root@localhost.com[/email]>, size=5205, nrcpt=1 (queue active)
Oct 14 08:30:03 localhost postfix/smtp[10233]: 454B844811E: to=<[email]sdfs@sci.com[/email]>, relay=mx.test.com[10.0.0.1]:25, delay=0.96, delays=0.22/0/0.13/0.61, dsn=2.0.0, status=sent (250 Ok: queued as D6D032CAAA6)
Oct 14 08:30:03 localhost postfix/qmgr[10207]: 454B844811E: removed

real    0m8.954s
user    0m5.846s
sys     0m0.566s

反复多试几次
我已经试了很多次了,还是一样的结果。
正则表达式优化的结果

/a|b|c/的情况下,perl会针对每个字符去匹配a,失败后再回溯匹配b,失败后再回溯匹配c
你匹配的又是maillog这种大文件,当然效率会非常非常低

而 /a/||/b/||/c/,因为abc都是常量,所以就不再按照正则表达式算法去匹配,
而是直接使用字符串匹配算法(正则优化的结果),当然要比正则表达式快很多。

所以,正则表达式中能不用 | 就不用 |
实在要用时,尽量提取出公共的部分,例如
  /this|that/
应当写成
  /th(is|at)/
这样perl会针对前两个字符 th 使用字符串匹配,
只有当真正遇到 th 之后,才会继续对3、4个字符用 | 回溯。
要比 this|that 快。

当然,过于优化了反而会降低代码可阅读性,自己找个平衡点吧。
楼上的,厉害!


QUOTE:
原帖由 odacharlee 于 2008-10-16 09:47 发表
正则表达式优化的结果

/a|b|c/的情况下,perl会针对每个字符去匹配a,失败后再回溯匹配b,失败后再回溯匹配c
你匹配的又是maillog这种大文件,当然效率会非常非常低

而 /a/||/b/||/c/,因为abc都是常量, ...

好!!!又学到了一点。
不错,很厉害!

比那个小丑好多了,哈哈


QUOTE:
原帖由 odacharlee 于 2008-10-16 09:47 发表
正则表达式优化的结果

/a|b|c/的情况下,perl会针对每个字符去匹配a,失败后再回溯匹配b,失败后再回溯匹配c
你匹配的又是maillog这种大文件,当然效率会非常非常低

而 /a/||/b/||/c/,因为abc都是常量, ...

学习了,,