I am trying to measure the execution time in seconds of an executable program invoked via subprocess. I do not want the output of the executable (either stderr or stdout) to be emitted.
I have tried the timeit and resource libraries, but neither accurately captures the time of the process, seemingly it only captures the timing in the Python worker thread.
This attempt below will lose the timing info b/c of the stderr redirect. However, w/o the stderr redirect, the command 'f_cmd' stderr output will be emitted.
def doWithTiming(f_cmd):
DEVNULL = open(os.devnull, 'w')
return subprocess.check_output([ "/usr/bin/time", "--format=%e seconds"] + f_cmd.split(), stderr=DEVNULL)
How do I ignore all output of f_cmd but retain the output of /usr/bin/time?
%e
/usr/bin/time
format is:To run a subprocess with suppressed stdout/stderr and get the elapsed time:
timeit.default_timer
istime.time
on POSIX on Python 2 therefore you should have got a valid time unless your usage oftimeit
is incorrect.The information returned by
resource
module does not include the "real" time, but you could use it to get "user" and "sys" times i.e., "Total number of CPU-seconds that the process spent in user mode." and "Total number of CPU-seconds that the process spent in kernel mode." correspondingly:You could start a subprocess using
psutil.Popen
and get while the child process is running additional info (cpu, memory, network connections, threads, fds, children, etc) in a portable way.See also, How to get the max memory usage of a program using psutil in Python.
For testing (to make sure that
time.time()
-based solution produces the same results), you could capture/usr/bin/time
output:Or using
-o
option with a named pipe:Your problem isn't with Python so much as it is with the behavior of the linux time utility. time will write to stderr after any stderr messages the process writes. You would get this effect running it from the shell. Subprocess is going to exactly copy the behavior of the shell command.
I would suggest you redirect stderr to suprocess.PIPE and then parse it. It shouldn't be too hard.
Alternatively, you could use -o with time to write your time info to an output file.