perl中读取大型日志文件的方法及其比较
我有一个巨大的日志文件(大约5-10百万行)。我需要遍历每一行并进行处理。我看到了巨大的运行时间 我知道有两种方法可以在perl中读取大型日志文件的方法及其比较,perl,file-io,Perl,File Io,我有一个巨大的日志文件(大约5-10百万行)。我需要遍历每一行并进行处理。我看到了巨大的运行时间 我知道有两种方法可以在perl中读取文件,如下所示 (1)如何比较不同方法的性能?有基准点机制吗 (2)最有效的方法是什么,为什么?有没有第三种更好的方法 一种选择是实现这两种方法并检查运行时。但在这里,我试图理解是什么让它们跑得更快或更慢。如果你能在这方面帮助我,我将不胜感激 方法1 open FOPEN, '<', $file or die $!; my @lines = <FOPE
perl
中读取文件,如下所示
(1)如何比较不同方法的性能?有基准点机制吗
(2)最有效的方法是什么,为什么?有没有第三种更好的方法
一种选择是实现这两种方法并检查运行时。但在这里,我试图理解是什么让它们跑得更快或更慢。如果你能在这方面帮助我,我将不胜感激
方法1
open FOPEN, '<', $file or die $!;
my @lines = <FOPEN>;
chomp @lines;
foreach (@lines) {
# do something on $_
}
打开FOPEN,方法2绝对是一条出路。方法1将把整个文件复制到内存中(在变量@lines内)。如果日志文件大于1 GB,则程序可能会崩溃。方法2将逐行迭代文件,并保持几乎恒定的内存使用率
希望这有帮助
编辑:(忘记谈论基准测试部分)
您可以使用类似的模块来比较两种方法在几个迭代中的性能。非常方便的工具。您会发现,对于一个非常大的文件,方法2的性能要比方法1好得多。除非您需要无序处理文件的行,否则您肯定应该在循环中读取它,因为将整个文件吸收到数组中只会浪费内存。Perl IO系统将通过缓冲文件读取并根据请求从缓冲区中传递每行数据来尽可能提高效率
也可能不需要对每一行进行chomp
。字符串末尾的备用换行符不太重要
根据您希望对文件执行的操作,可以将输入预处理为仅包含感兴趣信息的较小文件(或多个文件)
始终使用词法文件句柄,即
open my $fh, '<', $file or die $!;
while (<$fh>) {
# do something on $_
}
<代码>打开我的$FH,'如果文件大小很大,你正在读取整个文件,考虑用无阻塞IO来做SysRead,这里有一些例子:
或者搜索“perl sysread non blocking”chomp@lines
就可以了。它咀嚼数组中的每个元素。表示“如果您选择了一个列表,那么每个元素都将被选择,并返回删除的字符总数”。@Nikhil感谢您的回复。这真的很有帮助。由于缓存的原因,很难对文件IO进行基准测试。@ikegami-aha!现在我明白了为什么即使使用相同的代码,我也不能始终获得相同的性能@jkshah My 2 cents:在对IO密集型程序进行基准测试时,最好停止系统上所有IO绑定的程序/任务,然后将有问题的程序运行几次。在第一次运行时,磁盘上所有必要的数据块都将缓存在内存中,后续运行将显示一致的计时,因为所有必要的数据都应该来自操作系统磁盘缓存。当然,如果所讨论的IO集的大小超过了系统的内存限制,这些都不适用。@Nikhil但是我们通常使用的系统是共享的,并且许多用户在同一台机器上运行不同的作业。因此,我认为我将无法按照您的建议控制程序/任务@Nikhil,他正在尝试对IO本身进行基准测试,因此您的建议将完全使测试无效。谢谢您的回复。这真的很有帮助。
open my $fh, '<', $file or die $!;
while (<$fh>) {
# do something on $_
}