0

知っている人はいますか: Python でインターフェイスを設計して、呼び出し元がコード内の 2 つのポイントの間でどこに時間が費やされているかを追跡できるようにする方法はありますか?

たとえば、いくつかのコードがあり、それらに A、B、C、D のラベルを付けた場合、これらの部分の実行時間とコード全体の実行時間を追跡するにはどうすればよいでしょうか?

4

2 に答える 2

0

編集:関数/メソッドデコレーターのサポートが追加されました

私は次のようなことをしました:

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.002
sleep_four.start 34.001 2.000
sleep_four.stop 38.001 4.000
スリープ ファイブ スタート 38.001 0.000
スリープ ファイブ ストップ 43.002 5.000
終了 43.002 0.000

最初の列は指定されたキー、2 番目の列は最初のマークが設定されてからの時間差、3 番目の列は前のマークからの時間差です。

そして今、Steve Barnes の答えを見たので、デコレータのサポートを追加することはあまり良い補完ではありません。

于 2015-03-12T06:38:15.730 に答える