计算其输出由Python处理的外部程序

时间:2013-04-03 12:45:58

标签: python external timing

我想测量一个外部程序的执行时间,该程序的输出由我的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而不是等待处理所有输出?

2 个答案:

答案 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 5real时间为5秒,usersys次为0。

这是有效的,因为time输出实际执行时间的详细计算(不仅仅是挂起时间,这取决于正在运行的其他进程等),并且对标准错误输出也是如此。您可以解析标准错误并获取计时信息。

如果将输出数据编程为可能会干扰time命令解析的标准错误,则此方法可能不实用。

另外,我没有检查上面的代码是否会发生死锁(我不确定如果程序调用打印到标准错误会发生什么:程序是否会阻塞,直到标准错误缓冲区为止读取,如果Python程序正在读取标准输出,这可能不会发生?)。也就是说,如果您知道定时程序没有或很少有关于其标准错误的数据,我相信上面的代码不会死锁。