作者banco (Acoustic)
看板Perl
标题Re: [问题] 读文字档及搜寻字串的效率
时间Sun May 11 17:44:52 2008
※ 引述《banco (Acoustic)》之铭言:
: 平常自己都在 Linux 下操作程式
: 後来发现把相同程式转到 Windows 平台上执行
: 效率竟是天差地远 [注]
: 烦请诸位大德拨冗替小弟解惑
: (1)
: 我手边有个文字档, 约 27MB
: 在搜寻想要的字串时,
: 我一向用 @file = <FH>; 把内容倒进 @file 後再处理
: 然後再针对 @file 的内容, 一列一列地进行检查
: 不晓得 @file = <FH> 会不会是一个多余的动作
: 会不会直接用 foreach (<FH>) 效率会比较好些?
自问自答
以下原始程式 Unihan.txt 为 27MB 的文字档, 内含 1,116,642 行资料
程式执行花了 180 秒左右
1: open( Funi, "Unihan.txt" ) or die "no Unihan.txt";
2: @UniInfo = <Funi>;
3:
4: foreach (@UniInfo){
5: if( $_ =~ /^(U\S+)\t(\S+)\t(.*)$/ ){
6: $Unihan{$1}{$2} = $3;
7: }
8: }
9: close( Funi );
==修改一==
将第2行 @UniInfo = <Funi> 拿掉, 第4行换成 foreach( <Funi> )
程式执行花了 100 秒左右
另外原本第2行 @UniInfo = <Funi> 花了约 6 秒
==修改二==
同修改一, 另外在第5行的 regular expression 加上 modifier /g
程式执行花了 58 秒左右
==修改三==
同原始程式, 另外在第5行的 regular expression 加上 modifier /g
程式执行花了 53 秒左右
==粗略结论==
在不更改 regular expression、不增加任何 modifier 的条件下,
foreach 直接对 FileHandle <Funi> 会比 @UniInfo = <Funi> 来得快
但加上 modifier /g 之後, 情况整个相反,
即便 @UniInfo = <Funi> 会多花 6 秒
但先将资料倒入记忆体的速度优势在後来的 matching 展现出来
不过我一直对为何加上 /g 会提升速度感到好奇
因为从字面上的意义 global matching 来看,
无法想到为何会对速度产生影响?
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.216.35.194
1F:推 david220:foreach( <Funi> )改成while( <Funi> ) 05/18 19:40