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

时间:2017-05-11 12:45:46

标签: linux perl time system-calls

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

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

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

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

文件time.out将具有time命令的输出,而command.er具有command的stderr。不幸的是,括号打破了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的Arch系统上测试了它,而其他命令在/bin/shdash的Ubuntu系统上运行,这是一个不支持子shell括号的最小shell。

2 个答案:

答案 0 :(得分:3)

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

system("time (ls)")

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

但你想要

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

答案 1 :(得分:1)

$ 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::GetrusageBSD::Resource模块。