I have been doing some manual benchmark tests in my shell using the time
command. I would like to scale my benchmarks by writing a python script that both automates the tests and affords me access to the time data so that I can record it in the format of my choosing (likely a csv). I see there is the timeit
module, but that seems like it is more for benchmarking python code, where what I am trying to benchmark here are programs run in the command line.
This is what I have been doing manually:
time program -aflag -anotherflag
My initial attempt to implement this in a script looks like:
cmnd = ['time', 'program', 'aflag', 'anotherflag']
p = subprocess.Popen(cmnd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate
print out
print err
I can access the output of time
just fine – this is delivered to stderr, however I am not getting program
's output as expected in stdout. If I remove time
from cmnd
and change shell=False
to True, I then get the program's output in stdout – however obviously not time
's output, which is the whole point.
cmnd = ['program', 'aflag', 'anotherflag']
p = subprocess.Popen(cmnd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate
print out
print err
If I add time
back to cmnd with shell=True
, I get time's output but program
doesn't actually run.
How can I get both working?
Instead of trying to get this to work, why not use the functionality built into Python in the
resource
module?If you need to distinguish different child processes running simultaneously,
getrusage
isn't obviously not sufficient. In that case, you need to usewait4
or similar to get per-process resource usage. This makes your use ofPopen
more complicated. What you'd probably want to do for this case is subclass or fork thesubprocess
code (but make sure to usesubprocess32
backport if you're on 3.1 or earlier to avoid the bugs incommunicate
—and so that the class actually has the method you want to hook…) and change the_try_wait
method to usewait4
instead ofwaitpid
and stash the extra results in, e.g.,self.rusage
so you can access it later.I think something like this would work: