当前位置:  开发笔记 > 编程语言 > 正文

使用foreach或在Perl中迭代文件有什么区别?

如何解决《使用foreach或在Perl中迭代文件有什么区别?》经验,为你挑选了3个好方法。

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,用于行缓冲.



1> Alex Reynold..:

在大多数情况下,您可能不会注意到差异.但是,在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,用于行缓冲.


@j_random_hacker记忆差异更为重要和实用.你不应该依赖$ _来代替任何显着距离的代码,因为很多东西都会被践踏.
-1直到你提到while(){}践踏$ _而foreach没有(foreach localises $ _ first).当然这是*最重要的行为差异!

2> kmkaplan..:

在标量上下文中(即while)依次返回每一行.

在列表上下文(即foreach)中返回一个由文件中的每一行组成的列表.

你应该使用这个while结构.

有关更多信息,请参阅perlop - I/O操作符.

编辑:j_random_hacker正确地说

while () { … }

$_foreach没有践踏的情况下($_首先是本地化).当然这是重要的行为差异!



3> Ovid..:

除了之前的回复,使用的另一个好处while是您可以使用该$.变量.这是访问的最后一个文件句柄的当前行号(请参阅参考资料perldoc perlvar).

while ( my $line =  ) {
    if ( $line =~ /some_target/ ) {
        print "Found some_target at line $.\n";
    }
}

推荐阅读
云聪京初瑞子_617
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有