Measure program execution time with Perl "open"
I am working on a test suite library that uses Perl open
to run tests. It looks something like this:
open (MYOUT, "$myprog $arg1 $arg2 $arg3 2>&1 |") die "Bad stuff happened";
What I would really like to do is measure the execution time $myprog
. Unfortunately, simply grabbing the start and end times around the command open
just takes approximately the time it takes to start the process.
Is there a way to get the command open
to terminate the process (and therefore measure the time accurately), or perhaps something else to accomplish the same thing?
The key constraints are that we need to capture (possibly many) STDOUT
and STDERR
.
source to share
Since you open the tube you need time before open
ing, at least after reading
use warnings;
use strict;
use Time::HiRes qw(gettimeofday tv_interval sleep);
my $t0 = [gettimeofday];
open my $read, '-|', qw(ls -l) or die "Can't open process: $!";
while (<$read>)
{
sleep 0.1;
print;
}
print "It took ", tv_interval($t0), " seconds\n";
# close pipe and check
or so that the time of the whole process, after the call close
on the pipe (after everything has been read)
my $t0 = [gettimeofday];
open my $read, '-|', qw(ls -l) or die "Can't open process: $!";
# ... while ($read) { ... }
close $read or
warn $! ? "Error closing pipe: $!" : "Exit status: $?";
print "It took ", tv_interval($t0), " seconds\n";
close blocks and waits for the program to finish
Closing the pipe also waits for the process running on the pipe to finish - in case you want to see the output after that - and implicitly puts the value of the exit status of this command in
$?
[...]
To check the status see $? variable in perlvar and system
If a programmed program evolves and does not block wait
on its children, it will not result in their correct timing. In this case, you need to identify the resources they are using (files?) And keep track of that.
I would like to add that external commands should be carefully assembled to avoid corpus injection problems. Nice String :: ShellQuote module . See for example this answer and this answer
Using a module to capture threads will free you from the shell and possibly open up other ways to start and time to do this more reliably Nice Capture :: Tiny (and there are others).
Thanks to HรฅkonHรฆgland for the comments. Thanks to ikegami for setting me straight, use close
(not waitpid
).
source to share