如何实现一个界面来跟踪每个子部分的 运行 时间以及 python 部分的总 运行 时间
how to implement a interface to keep track of runtime of each sub-sections and also the total run time of the section in python
有没有人知道:如何在python中设计一个接口,以便调用者可以跟踪一段代码中两点之间花费的时间?
例如:如果我们有几段代码,我们将它们标记为 A、B、C、D,那么我们如何跟踪这些代码段的运行时间以及整个代码段的运行时间?
这听起来像是您可以充分利用装饰器的东西,例如 entryExit decorator 可以记录在每个装饰函数中花费的时间:
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()"
编辑: 现在有了 function/method 装饰器支持
我做过类似的事情:
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
输出:
start 0.000 ---
sleep-thirty.start 1.999 1.999
sleep-thirty.stop 32.001 30.002
sleep_four.start 34.001 2.000
sleep_four.stop 38.001 4.000
sleep-five.start 38.001 0.000
sleep-five.stop 43.002 5.000
end 43.002 0.000
第一列是指定键,第二列是自设置第一个标记以来的时间增量,第三列是自上一个标记以来的时间增量。
现在我看到了 Steve Barnes 的回答,添加装饰器支持并不是一个很好的补充。
有没有人知道:如何在python中设计一个接口,以便调用者可以跟踪一段代码中两点之间花费的时间?
例如:如果我们有几段代码,我们将它们标记为 A、B、C、D,那么我们如何跟踪这些代码段的运行时间以及整个代码段的运行时间?
这听起来像是您可以充分利用装饰器的东西,例如 entryExit decorator 可以记录在每个装饰函数中花费的时间:
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()"
编辑: 现在有了 function/method 装饰器支持
我做过类似的事情:
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
输出:
start 0.000 --- sleep-thirty.start 1.999 1.999 sleep-thirty.stop 32.001 30.002 sleep_four.start 34.001 2.000 sleep_four.stop 38.001 4.000 sleep-five.start 38.001 0.000 sleep-five.stop 43.002 5.000 end 43.002 0.000
第一列是指定键,第二列是自设置第一个标记以来的时间增量,第三列是自上一个标记以来的时间增量。
现在我看到了 Steve Barnes 的回答,添加装饰器支持并不是一个很好的补充。