%e
/usr/bin/time
格式为:
进程使用的实际流逝(墙钟)时间,以秒为单位。
要运行一个抑制stdout/stderr并获取经过的时间的子进程:
import os
import time
from subprocess import check_call, STDOUT
DEVNULL = open(os.devnull, 'wb', 0)
start = time.time()
check_call(['sleep', '1'], stdout=DEVNULL, stderr=STDOUT)
print("{:.3f} seconds".format(time.time() - start))
timeit.default_timer
在Python 2的POSIX上等同于time.time
,因此,除非您使用timeit
的方式不正确,否则应该可以获得有效的时间。
resource
模块返回的信息不包括"real"时间,但您可以使用它来获取"user"和"sys"时间,即进程在用户模式下花费的"CPU秒数"和在内核模式下花费的"CPU秒数",分别如下所示:
import os
import time
from subprocess import Popen, STDOUT
DEVNULL = open(os.devnull, 'wb', 0)
start = time.time()
p = Popen(['sleep', '1'], stdout=DEVNULL, stderr=STDOUT)
ru = os.wait4(p.pid, 0)[2]
elapsed = time.time() - start
print(" {:.3f}real {:.3f}user {:.3f}system".format(
elapsed, ru.ru_utime, ru.ru_stime))
您可以使用psutil.Popen
启动子进程,并以可移植的方式获取在子进程运行时的其他信息(CPU、内存、网络连接、线程、文件描述符、子进程等)。
另请参见:如何使用Python中的psutil获取程序的最大内存使用情况。
为了进行测试(确保基于time.time()
的解决方案产生相同的结果),您可以捕获/usr/bin/time
的输出:
import os
from collections import deque
from subprocess import Popen, PIPE
DEVNULL = open(os.devnull, 'wb', 0)
time_lines_count = 1
p = Popen(['/usr/bin/time', '--format=%e seconds'] +
['sleep', '1'], stdout=DEVNULL, stderr=PIPE)
with p.stderr:
q = deque(iter(p.stderr.readline, b''), maxlen=time_lines_count)
rc = p.wait()
print(b''.join(q).decode().strip())
或者使用带有命名管道的-o
选项:
import os
from contextlib import contextmanager
from shutil import rmtree
from subprocess import Popen, STDOUT
from tempfile import mkdtemp
DEVNULL = open(os.devnull, 'wb', 0)
@contextmanager
def named_pipe():
dirname = mkdtemp()
try:
path = os.path.join(dirname, 'named_pipe')
os.mkfifo(path)
yield path
finally:
rmtree(dirname)
with named_pipe() as path:
p = Popen(['/usr/bin/time', '--format=%e seconds', '-o', path] +
['sleep', '1'], stdout=DEVNULL, stderr=STDOUT)
with open(path) as file:
time_output = file.read().strip()
rc = p.wait()
print(time_output)