如何获得Perl系统调用的CPU时间? [英] How can I get the CPU time for a perl system call?

查看:93
本文介绍了如何获得Perl系统调用的CPU时间?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a perl script that calls external executables using system(). I would like to measure the CPU seconds taken by these external programs. Ideally, I would like to run them using the shell builtin time command (this is on a Linux system). Something like this:

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

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

Now, time prints its output to stderr, but in order to do so, launches the command it is given in a separate subshell. This means that in order to capture time's output when running manually in the shell, you need to explicitly use a subshell and redirect the subshell's stderr:

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

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

The file time.out will have the output of the time command while command.er has the stderr of command. Unfortunately, the parentheses break perl's system call:

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

这意味着我无法捕获time的输出.更令人担忧的是,这似乎与版本有关:

And this means I can't capture the output of time. To make matters wors, this seems to be version dependent:

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

但是,如果我尝试使用更新的版本进行同样的操作:

But if I try the same thing with a newer version:

$ 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值,因此仅记录开始时间和结束时间将无济于事.如果有必要,我愿意使用专用模块,尽管我更喜欢让我使用外壳的time的技巧.

Unfortunately, I need this to run on a production machine so upgrading Perl is not an option. So, how can I time a system call in Perl 5.18? I need the user and sys values, so simply recording the start and end times won't help. I am willing to use a dedicated module if that's necessary although I would prefer a trick that lets me use the shell's time.

更新:事实证明,行为上的差异不是由于更新的perl版本引起的,而是因为我在/bin/shbash的Arch系统上测试了它,而其他命令正在运行/bin/shdash的Ubuntu系统,这是一个不支持子外壳括号的最小外壳.

UPDATE: it turns out the difference in behavior is not because of the newer perl version but, instead, it is because I tested it on an Arch system whose /bin/sh is bash while the other commands were being run on Ubuntu systems whose /bin/sh is dash, a minimal shell that doesn't support parentheses for subshells.

推荐答案

您可以使用捕获:: Tiny 捕获Perl中几乎所有东西的STDOUT和STDERR.

You can use Capture::Tiny to capture the STDOUT and STDERR of pretty much anything in Perl.

use Capture::Tiny 'capture';

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

print $stderr;

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

For some reason the output is missing some whitespace on my system, but is clear enough to parse out what you need.

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

这篇关于如何获得Perl系统调用的CPU时间?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆