在perl中读取大型日志文件的方法及其比较

jks*_*hah 2 perl file-io

我有一个巨大的日志文件(约5-10万行).我需要遍历每一行并进行处理.我看到了巨大的运行时间.

我知道有两种读取文件的方法,perl如下所示.

(1)如何比较不同方法的性能?任何基准标记机制?

(2)什么是最有效的方式和原因?有没有第三种更好的方法?

一种选择是实现这两种方法并检查运行时.但在这里,我试着了解是什么让他们跑得更快或更慢.如果你能在这方面帮助我,那将是件好事.

方法1

open FOPEN, '<', $file or die $!;
my @lines = <FOPEN>;
chomp @lines;
foreach (@lines) {
    # do something on $_
}
Run Code Online (Sandbox Code Playgroud)

方法2

open FOPEN, '<', $file or die $!;
while (<FOPEN>) {
    chomp;
    # do something on $_
}
Run Code Online (Sandbox Code Playgroud)

Bor*_*din 8

除非你需要按顺序处理文件的行,否则你肯定应该在while循环中读取它,因为将整个文件吸收到数组中只会浪费内存.Perl IO系统将通过缓冲文件读取并在请求时从缓冲区传递每行数据来使其尽可能高效.

chomp每条线也可能没有必要.字符串末尾的备用换行符不太重要.

根据您对文件的处理方式,将输入预处理为仅包含感兴趣信息的较小文件(或多个文件)可能是合适的.

始终使用词法文件句柄,即

open my $fh, '<', $file or die $!;
while (<$fh>) {
    # do something on $_
}
Run Code Online (Sandbox Code Playgroud)

这与效率无关; 这简直是​​一种很好的做法.


Nik*_*hil 7

方法2绝对是要走的路.方法1将整个文件复制到内存中(在变量@lines内).如果您的日志文件大于1 GB,则期望程序崩溃.方法2将逐行遍历文件,并保持几乎恒定的内存使用量.

希望这可以帮助.

编辑:(忘了谈基准部分)

您可以使用像Benchmark这样的模块来比较两种方法在多次迭代中的性能.一个非常方便的工具.您会发现方法2将以非常大的文件的优势超出方法1.

  • `chomp @ lines`很好.它会扼杀数组的每个元素.[文档](http://perldoc.perl.org/functions/chomp.html)说*"如果你选择一个列表,每个元素都会被选中,并且会删除删除的字符总数"*. (3认同)