我想测量一个外部程序的执行时间,该程序的输出由我的Python脚本使用。
调用extprogram
产生输出的程序,此时我做了类似的事情:
import time
import subprocess
def process_output(line):
...
...
return processed_data
all_processed_data = []
ts = time.time()
p = subprocess.Popen("extprogram", stdout=subprocess.PIPE)
for line in p.stdout:
all_processed_data.append(process_output(line))
te = time.time()
elapsed_time = te - ts
这不能按预期工作,因为我测量的是执行extprogram
的时间加上处理输出所需的时间。
extprogram
产生大量数据,因此我想在我的Python程序中使用循环“流”输出,就像我现在所做的那样。
如何在te
终止时评估extprogram
而不是等待处理所有输出?
答案 0 :(得分:1)
以下内容仍使用“挂钟”时间,但可能是使用主机系统时间命令的替代方法。执行和时间被分成单独的线程,并且可以在执行任何处理之前停止计时器。
from multiprocessing import Event
import threading
import time
import subprocess
def timing(event):
print "timer starts"
ts = time.time()
event.wait()
te = time.time()
elapsed_time = te - ts
print "Elapsed Time " + str(elapsed_time)
def execution(event):
for i in range(0,1000):
p = subprocess.Popen("ls", stdout=subprocess.PIPE)
event.set()
if __name__ == '__main__':
event = Event()
e = threading.Thread(target=execution, args=(event,))
t = threading.Thread(target=timing, args=(event,))
t.start()
e.start()
while not event.is_set():
print "running..."
time.sleep(1)
这给了我以下输出:
timer starts
running...
running...
Elapsed Time 1.66236400604
或者您可以从输出处理中分割接收'extprogram'的输出。
例如:
ts = time.time()
p = subprocess.Popen("extprogram", stdout=subprocess.PIPE)
for line in p.stdout:
tempdata.append(line)
te = time.time()
elapsed_time = te - ts
for line in tempdata:
all_processed_data.append(process_output(line))
答案 1 :(得分:1)
由于您使用的是Unix,因此可以使用time
命令。这是原则:
import sys
import subprocess
p = subprocess.Popen(["time", "ls"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
for line in p.stdout: # ls output
sys.stdout.write(line)
time_output = p.stderr.readlines()
print "Stderr:", ''.join(time_output)
在我的机器上,这给出了:
Stderr: 0.01 real 0.00 user 0.00 sys
总处理器时间是user
+ sys
时间(real
是挂钟时间,通常不代表程序使用的处理器时间:例如, sleep 5
,real
时间为5秒,user
和sys
次为0。
这是有效的,因为time
输出实际执行时间的详细计算(不仅仅是挂起时间,这取决于正在运行的其他进程等),并且对标准错误输出也是如此。您可以解析标准错误并获取计时信息。
如果将输出数据编程为可能会干扰time
命令解析的标准错误,则此方法可能不实用。
另外,我没有检查上面的代码是否会发生死锁(我不确定如果程序调用打印到标准错误会发生什么:程序是否会阻塞,直到标准错误缓冲区为止读取,如果Python程序正在读取标准输出,这可能不会发生?)。也就是说,如果您知道定时程序没有或很少有关于其标准错误的数据,我相信上面的代码不会死锁。