如何获得 perl 系统调用的 CPU 时间?

How can I get the CPU time for a perl system call?

我有一个使用 system() 调用外部可执行文件的 perl 脚本。我想测量这些外部程序所用的 CPU 秒。理想情况下,我想 运行 使用 shell 内置 time 命令(这是在 Linux 系统上)。像这样:

system("time /path/to/command")

现在,time 将其输出打印到 stderr,但为了这样做,启动在单独的子 shell 中给出的命令。这意味着为了在 shell 中手动 运行ning 时捕获时间输出,您需要显式使用 subshell 并重定向 subshell 的标准错误:

$ time ( command > command.log 2> command.er) 2> time.out

文件 time.out 将具有 time 命令的输出,而 command.er 具有 command 的标准错误。不幸的是,括号破坏了 perl 的系统调用:

$ time ( ls ) 2> er ## works
$ perl -e 'system("time (ls)")'
sh: 1: Syntax error: word unexpected (expecting ")")

这意味着我无法捕获 time 的输出。更糟糕的是,这似乎与版本有关:

$ perl --version | head -n2
This is perl 5, version 18, subversion 2 (v5.18.2) built for x86_64-linux-gnu-thread-multi

但是如果我用更新的版本尝试同样的事情:

$ perl --version | head -n2
This is perl 5, version 24, subversion 1 (v5.24.1) built for x86_64-linux-thread-multi
$ perl -e 'system("time (ls)")'
file1

real    0m0.002s
user    0m0.000s
sys     0m0.000s

不幸的是,我需要在生产机器上 运行 使用它,因此无法升级 Perl。那么,我如何在 Perl 5.18 中为系统调用计时?我需要 usersys 值,因此简单地记录开始和结束时间无济于事。如果有必要,我愿意使用专用模块,尽管我更喜欢让我使用 shell 的 time 的技巧。


更新:事实证明行为上的差异不是因为较新的 perl 版本,而是因为我在 /bin/shbash 而其他命令在 Ubuntu 系统上被 运行 其 /bin/shdash,最小的 shell 不支持 subshells 的括号.

您可以使用 Capture::Tiny 捕获 Perl 中几乎所有内容的 STDOUT 和 STDERR。

use Capture::Tiny 'capture';

my ($stdout, $stderr, $exit) = capture { system "time ls" };

print $stderr;

出于某种原因,输出在我的系统上缺少一些空格,但足够清晰,可以解析出您需要的内容。

0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 2272maxresident)k
0inputs+8outputs (0major+111minor)pagefaults 0swaps

您已使用 bash 测试了该命令,但您已将其传递给 sh

system("time (ls)")

的缩写
system("/bin/sh", "-c", "time (ls)")

但你想要

system("/bin/bash", "-c", "time (ls)")
$ time ( ls ) 2> er ## works
$ perl -e 'system("time (ls)")'
sh: 1: Syntax error: word unexpected (expecting ")")

问题是,在第一种情况下,您的 shell 可能是 /bin/bash,而在第二种情况下,它是 /bin/sh。如果你想 运行 你的命令与另一个 shell,你可以使用 system LIST 形式:

system("/bin/bash", "-c", "time(ls)")

注意 1:有 PERL5SHELL environmnet 值,但这似乎 在 Win32 上生效。

注2:如果你想测量子进程的CPU时间,你可以使用Unix::Getrusage or BSD::Resource模块。