我FILE
在Perl中有一个文件句柄,我想迭代文件中的所有行.以下是否有区别?
while () { # do something }
和
foreach () { # do something }
Alex Reynold.. 37
在大多数情况下,您可能不会注意到差异.但是,在foreach
逐行执行之前将每行读入列表(而不是数组),而一次while
读取一行.由于foreach
将使用更多内存并需要预先处理时间,因此通常建议使用while
迭代文件的行.
编辑(通过Schwern):foreach
循环等同于:
my @lines = <$fh>; for my $line (@lines) { ... }
不幸的是,Perl没有像范围运算符(1..10
)一样优化这种特殊情况.
例如,如果我用for
循环和while
循环读取/ usr/share/dict/words 并在它们完成后让它们休眠,我可以ps
用来查看进程消耗了多少内存.作为一个控件我已经包含了一个程序,它打开文件,但没有做任何事情.
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND schwern 73019 0.0 1.6 625552 33688 s000 S 2:47PM 0:00.24 perl -wle open my $fh, shift; for(<$fh>) { 1 } print "Done"; sleep 999 /usr/share/dict/words schwern 73018 0.0 0.1 601096 1236 s000 S 2:46PM 0:00.09 perl -wle open my $fh, shift; while(<$fh>) { 1 } print "Done"; sleep 999 /usr/share/dict/words schwern 73081 0.0 0.1 601096 1168 s000 S 2:55PM 0:00.00 perl -wle open my $fh, shift; print "Done"; sleep 999 /usr/share/dict/words
该for
程序消耗了大约32兆的实内存(RSS
列)来存储我的2.4 meg/usr/share/dict/words的内容.该while
循环仅存储一行,耗时仅为70k,用于行缓冲.
在大多数情况下,您可能不会注意到差异.但是,在foreach
逐行执行之前将每行读入列表(而不是数组),而一次while
读取一行.由于foreach
将使用更多内存并需要预先处理时间,因此通常建议使用while
迭代文件的行.
编辑(通过Schwern):foreach
循环等同于:
my @lines = <$fh>; for my $line (@lines) { ... }
不幸的是,Perl没有像范围运算符(1..10
)一样优化这种特殊情况.
例如,如果我用for
循环和while
循环读取/ usr/share/dict/words 并在它们完成后让它们休眠,我可以ps
用来查看进程消耗了多少内存.作为一个控件我已经包含了一个程序,它打开文件,但没有做任何事情.
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND schwern 73019 0.0 1.6 625552 33688 s000 S 2:47PM 0:00.24 perl -wle open my $fh, shift; for(<$fh>) { 1 } print "Done"; sleep 999 /usr/share/dict/words schwern 73018 0.0 0.1 601096 1236 s000 S 2:46PM 0:00.09 perl -wle open my $fh, shift; while(<$fh>) { 1 } print "Done"; sleep 999 /usr/share/dict/words schwern 73081 0.0 0.1 601096 1168 s000 S 2:55PM 0:00.00 perl -wle open my $fh, shift; print "Done"; sleep 999 /usr/share/dict/words
该for
程序消耗了大约32兆的实内存(RSS
列)来存储我的2.4 meg/usr/share/dict/words的内容.该while
循环仅存储一行,耗时仅为70k,用于行缓冲.
在标量上下文中(即while
)
依次返回每一行.
在列表上下文(即foreach
)中
返回一个由文件中的每一行组成的列表.
你应该使用这个while
结构.
有关更多信息,请参阅perlop - I/O操作符.
编辑:j_random_hacker正确地说
while () { … }
在
$_
foreach没有践踏的情况下($_
首先是本地化).当然这是最重要的行为差异!
除了之前的回复,使用的另一个好处while
是您可以使用该$.
变量.这是访问的最后一个文件句柄的当前行号(请参阅参考资料perldoc perlvar
).
while ( my $line =) { if ( $line =~ /some_target/ ) { print "Found some_target at line $.\n"; } }