如何在 Python 中实现一个接口来跟踪每个子部分的运行时以及该部分的总运行时间



有没有人知道:如何在python中设计一个接口,以便对于调用者来说,它可以跟踪一段代码中两点之间的时间?

例如:如果我们有几段代码,我们将它们标记为A,B,C,D,那么我们如何跟踪这些片段的运行时以及整个代码段的运行时呢?

这听起来像是你可以很好地使用装饰器的东西,比如 entryExit 装饰器可以记录在每个装饰函数中花费的时间:

class entryExit(object):
    def __init__(self, f):
        self.f = f
    def __call__(self):
        print "Entering", self.f.__name__
        self.f()
        print "Exited", self.f.__name__
@entryExit
def func1():
    print "inside func1()"
@entryExit
def func2():
    print "inside func2()"

编辑:现在支持函数/方法装饰器

我做了这样的事情:

import timeit
from collections import OrderedDict

class TimeMarkContextManager(object):
    def __init__(self, mgr, key):
        self.mgr = mgr
        self.key = key
    def __enter__(self):
        self.mgr.mark("%s.start" % self.key)
    def __exit__(self, *args, **kwargs):
        self.mgr.mark("%s.stop" % self.key)
class TimeMark(object):
    def __init__(self):
        self.marks = OrderedDict()
    def mark(self, key):
        self.marks[key] = timeit.default_timer()
    def manager(self, key):
        return TimeMarkContextManager(self, key)
    def pprint(self):
        base = self.marks.values()[0]
        last = None
        for (k,v) in self.marks.iteritems():
            delta_base = "%.3f" % (v - base)
            delta_last = "%.3f" % (v - last) if last is not None else "---"
            print("%-20s  %8s  %8s" % (k, delta_base, delta_last))
            last = v
def TimeMe(mgr, key=None):
    def TimeDeco(f):
        def func_wrapper(*args, **kwargs):
            k = f.__name__ if key is None else key
            mgr.mark("%s.start" % k)
            rv = f(*args, **kwargs)
            mgr.mark("%s.stop"  % k)
            return rv
        return func_wrapper
    return TimeDeco

然后,您可以按如下方式使用它:

import time                 # Only required for time.sleep()
tm = TimeMark()             # Initialize the TimeMark object
@TimeMe(tm)                 # Decorate a function, don't give it a special key
def sleep_four():           #  (it will use the function name as a key)
    time.sleep(4)
@TimeMe(tm, "sleep-five")   # Decorate a function, override the default tag
def sleep_five():
    time.sleep(5)
tm.mark("start")            # Create a mark called "start"
time.sleep(2)
# Use a context manager to time a block
with tm.manager("sleep-thirty"):
    time.sleep(10)
    time.sleep(10)
    time.sleep(10)
time.sleep(2)
sleep_four()                # Call the sleep_four function.
                            #   It'll show up as "sleep_four" (note underscore)
sleep_five()                # Call the sleep_five function.
                            #   It'll show up as "sleep-five" (note hyphen)
tm.mark("end")              # Create a mark called "stop"
tm.pprint()                 # Print a list of timemarks

哪些输出:

开始 0.000 ---睡眠-三十.开始 1.999 1.999睡眠-三十.停止 32.001 30.002sleep_four.开始 34.001 2.000sleep_four.停止 38.001 4.000睡眠-五.开始 38.001 0.000睡眠-五.停止 43.002 5.000结束 43.002 0.000
第一列是指定的键,第二列是自

设置第一个标记以来的时间增量,第三列是自上一个标记以来的时间增量。

现在我看到了史蒂夫·巴恩斯的答案,添加装饰器支持将不是一个很好的补充。

相关内容

  • 没有找到相关文章

最新更新