5

我有一个 perl 脚本,我在其中写出一个非常大的日志文件。目前我用“传统”的 Perl 方式写出我的文件:

open FILE, ">", 'log.txt';
print FILE $line;
.....
close FILE;

在读取文件时,我听说过很多关于File::Slurp的好消息,以及它如何极大地改善运行时。我的问题是,使用 File::Slurp 会更快地写出我的日志文件吗?我问是因为用 perl 写出一个文件看起来很简单,我不知道 File::Slurp 如何真正优化它。

4

2 回答 2

9

在某些情况下,这些File::Slurp实用程序总体上可能比等效的流式实现要快一些,但文件 I/O 比仅基于内存和 CPU 速度的任何东西慢得多,以至于它几乎总是限制资源。

我从未听说过任何File::Slurp可以大大改善运行时的声明,并且希望看到对这种效果的引用。我认为它是一个更有效的解决方案的唯一方法是程序需要随机访问文件或必须多次读取它。因为数据一次全部在内存中,所以访问任何数据都没有开销,但在这种情况下,我的偏好是Tie::File让数据看起来好像所有数据都同时可用,对速度的影响很小,内存开销也少得多

事实上,很可能是调用read_file使该过程在用户看来要慢得多。如果文件非常大,那么读取所有文件并将其拆分为行所花费的时间可能会导致处理开始之前的明显延迟,而打开文件并读取第一行通常看起来是瞬时的

这同样适用于程序结束时。调用write_file将数据组合到磁盘块并将其分页到文件中,将比简单地关闭文件花费更长的时间

一般来说,传统的流式输出方法更可取。它对速度的影响很小或没有影响,并通过增量保存数据来避免数据丢失,而不是等到大量数据在内存中积累后才发现由于某种原因无法将其写入磁盘

我的建议是,File::Slurp当您有随机访问可以显着简化程序代码的小文件时,您保留使用。即使这样也没有错

my @data = do {
  open my $fh, '<', 'my_file' or die $!;
  <$fh>;
};

用于输入,或

open my $fh, '>', 'out_file' or die $!;
print { $fh } for @data;

用于输出。特别是在您的情况下,您正在处理一个非常大的日志文件,我认为毫无疑问您应该坚持使用流式输出方法

于 2012-09-03T12:03:32.063 回答
8

File::Slurp主要是一个便利功能。而不是编写通常的open, while read/write,close代码你只有一行read_filewrite_file.

但是,我不知道它是否比您自己的代码快。它是用 Perl 编码的,而不是用 C 编码的。此外,在使用它的数组变体的情况下,write_file $file_name, @lines它在内存方面也可能效率低下,因为它首先将所有数组行连接成一个单一的标量,然后再将其写出。

但是,它确实使用syswrite而不是缓冲写入。它可以安全地做到这一点,因为它是在其生命周期内访问文件句柄的唯一函数。所以是的,因此它可能会更快。

于 2012-09-03T06:40:41.163 回答