[英]does Perl's Capture::Tiny::capture() avoid disk io required when using system()?
从 Perl 脚本调用外部程序时,Capture::Tiny 是否避免使用 system() 时需要磁盘 io? 使用两者时,我获得的性能基本相同。 一位同事正在使用我的代码并告诉我它正在锤击他的磁盘。 在我的本地机器上运行并写入本地磁盘时,我(也许)没有这个问题。
我以前是这样做的:
open($fhStdin, ">stdin.txt");
print $fhStdin "some text\n";
close($fhStdin);
system("cmd < stdin.txt 1> stdout.txt 2> stderr.txt");
# open and read stdout.txt
# open and read stderr.txt
并改为:
($stdout, $stderr, $exit) = capture {
open($fhStdin, '| cmd');
print $fhStdin "some text\n";
close($fhStdin);
};
但 NYTProf 告诉我,它们运行所需的时间基本上相同(但 NYTProf 从子例程时间中删除了磁盘 io 开销)。 所以我想知道 capture() 是否正在写入引擎盖下的临时文件? (我尝试阅读 Tiny.pm 源代码,但很惭愧地说我无法从中分辨出来。)
感谢您提供任何提示。
Capture::Tiny::capture的文档指出确实使用了文件
捕获通常是对匿名临时文件句柄进行的。
这可以在_capture_tee子的源代码中看到,用作所有方法的通用例程。 大约进行到一半时,我们发现调用File::Temp->new
发生,除非要使用命名文件(见下文)。 可以小心地跟踪其余的处理过程。 †
文档继续提供一种通过命名文件来监视所有这些的方法
要通过命名文件进行捕获(例如从外部监视长时间运行的捕获),请提供自定义文件句柄作为选项对的尾随列表:
my $out_fh = IO::File->new("out.txt", "w+"); my $err_fh = IO::File->new("out.txt", "w+"); capture { ... } stdout => $out_fh, stderr => $err_fh;
文件句柄必须是读/写和可查找的。 在捕获操作期间修改文件或文件句柄将产生不可预测的结果。 捕获可能会更改它们上现有的 IO 层。
(如果这样做,那么对File::Temp
的调用将不会进行,如上所述。请参阅源代码。)
如果此磁盘活动有问题,您可以使用管道打开读取cmd
的输出(首先将其输入写入文件),或使用qx (反引号)。 但是你必须合并或重定向STDERR
并通过更多的箍来检查和处理错误。
另一种选择是使用IPC::Run3 。 虽然它也使用文件,但它提供了更多的选项,可以用来减少磁盘 I/O,或者可能完全避免使用磁盘。 (使用打开为标量(内存中)的文件句柄进行调用的想法不起作用,因为这不是真正的文件句柄。 ‡ )
“核”选项是更复杂的IPC::Run ,它可以在不使用磁盘的情况下进行输出。
†粗略的草图
将所有方法“调度”到_capture_tee
是在开始时完成的,在goto &func
将其带走之前,一组标志被unshift
ed 到@_
,以区分方法。 对于capture
这是1,1,0,0
,它在1,1,0,0
设置变量$do_stdout
和$do_stderr
_capture_tee
。 然后使用这些来设置%do
哈希,这些键被迭代以设置$stash
。
如果将额外的参数传递给capture
(对于命名文件),则设置$stash->{capture}
,否则分配File::Temp
对象。 $stash
稍后会传递给发生重定向的_open_std
。
还有更多,但主要与本地化球体和图层的操作有关。
‡最常见的调用写入标量
run3 \@cmd, \my $in, \my $out, \my $err;
但这使用文件,如How it works下的文档中所述。
试图通过写入打开为标量的文件句柄来欺骗它不使用文件
my @cmd = qw(ls -l .);
open my $fh, '>', \my $cmd_out; # not a real filehandle ...
run3 \@cmd, \undef, $fh; # ... so this won't work
中止
run3(): Invalid argument redirecting STDOUT at ...
这是因为对标量的open
不会设置真正的文件句柄。 看到这个帖子。
如果文件句柄被打开到一个文件,这将按预期工作,写入该文件。 与Capture::Tiny
相比,这可能会导致更高效的磁盘 I/O 操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.