0

当我陈述以下内容时,我的理解是否正确:

在 while(<>) 循环中测试 $ARGV(即文件名)的某些条件会浪费 CPU 周期。首先测试文件名更有效,然后在 while() 循环中相应地处理每一行。这样,它就不会在每次抓取一行数据时重复检查文件名。

或者钻石操作员是否做了一些魔术来使其与后者一样高效?

4

2 回答 2

2

它是在浪费 CPU 周期吗?

您正在运行Perl。在VM上运行。你知道一个简单的全局变量查找意味着多少指针取消引用吗?你为什么要关心周期?/s

尽管<>运算符确实暗示了相当多的魔法,但这并没有优化您的循环。因此,在

my $lastfile = "";
while (<>) {
  say "file changed to ", $lastfile = $ARGV if $lastfile ne $ARGV;
  print "> $_";
}

将对ne每一行执行检查。如果您正在优化代码大小或开发时间,这是完全可以接受的。如果您正在优化执行的操作码总数,有时显式打开文件可能会更便宜:

use autodie;
for my $file (@ARGV) {
  open my $fh, "<", $file;
  say "file changed to $file";
  while (<$fh>) {
    print "> $_";
  }
}

我个人觉得这种形式更优雅(单一分配形式),反正也不会那么长。但是在一个快速的单行器中,我会使用第一个解决方案,因为我的脚本可能已经运行了一千次,而我仍在编写更长的表单。

于 2013-07-25T05:31:18.630 回答
0

作为概念证明(见下文),我在一个 10 亿行的文件上运行了 amon 所示的两个脚本(我分别将它们命名为 poc.pl 和 poc2.pl)。前者慢了 21.7%。总之,这仅在处理大量行时才有意义。在这种情况下,低级语言可能是更好的选择。

bash $  wc -l large.log
1000000000 large.log
bash $  time perl poc.pl large.log >/dev/null
  291.16s real   289.89s user     0.73s system
bash $  time perl poc2.pl large.log >/dev/null
  239.29s real   238.58s user     0.53s system
于 2013-07-26T01:17:40.000 回答