4

最初のコールバックが起動されてから最終結果まで、Deferredの実行にかかる時間を知りたいです。

おそらく非侵襲的な方法でそれを行う方法についてのアイデアはありますか(実行時間を追跡するためにコールバック関数を変更しないことを意味します)?

4

3 に答える 3

8

「twistd」の助けを借りてプログラムを実行している場合、ねじれたコードのプロファイリングに役立つオプション「--profile」があります。

twistd "other options" --profile=statsfile --profiler=cProfile --savestats

統計を表示するには:

import pstats
stats = pstats.Stats('statsfile')
stats.sort_stats('time').print_stats()

コールバックは、遅延オブジェクトが起動された直後に実行されます。ただし、即時は、遅延チェーン内の各コールバックを実行する必要があり、独自の実行時間があることを意味します。また、さまざまなコードには、リアクター ループを含む実行のための独自の時間枠があります。

つまり、「すぐに」という言葉は、できるだけ早く言うことです。

次の悪い例を考えてみましょう:

from twisted.internet import reactor, defer
import time

def timeit(func):
    def wrapper(*arg):
        t1 = time.time()
        res = func(*arg)
        t2 = time.time()
        print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0)
        return res
    return wrapper

d = defer.Deferred()

@timeit
def callfunc1(result):
    print 'XXXXX'

@timeit   
def callfunc2(result):
    print 'YYYYY'

d.addCallback(callfunc1)   
d.addCallback(callfunc2)  
t1 = time.time()
d.callback(True)
t2 = time.time()
print '%0.3f ms' % ((t2-t1)*1000.0)

出力:

XXXXX
callfunc1 took 0.039 ms
YYYYY
callfunc2 took 0.005 ms
0.108 ms

ここで、上記のコードを微調整してリアクターと callLater を含めると

于 2010-10-27T17:39:16.367 に答える
3

アプリをプロファイリングする必要があると思います。次の方法に従ってください。

このツールをインストールhttp://kcachegrind.sourceforge.net/html/Home.html

ねじれたアプリを起動して、生データを収集します。

twistd --savestats -n --profile=myapp.hotshot myapp

よりも、「hotshot」を「calltree」に変換して、次を実行します。

hotshot2cg myapp.hotshot > myapp.calltree

Kcachegrind ツールでコールツリーを表示できるようになりました。

kcachegrind myapp.calltree

このツールを使用すると、ねじれたイベント ループのコール グラフを表示できます。実行時間はパーセントで表示されます。コードにパッチを当てる必要はありません。このツールを実行して確認してください。

メモリをチェックするための PS: メモリ使用量を追跡するために guppy/heapy を使用する方法

于 2013-03-15T02:51:09.687 に答える
1

プロファイリングは、私が達成したいことに対して少しやり過ぎです。

私は、既存のコードに大きな変更を加えることを意味しないソリューションになりましたが、決して「普遍的」ではありません:

私の元のコードは次のようなものでした:

def myfunc(*args):
    d = Deferred()
    d.addCallback(cb1)
    ...
    d.addCallback(lambda x: MyObject(x))

私は今持っています:

def myfunc(*args):
    init_time = time.time()
    d = Deferred()
    d.addCallback(cb1)
    ...
    d.addCallback(lambda x: MyObject(x, init_time))

class MyObject:
    def __init__(self, *args):
        ...
        self.exec_time = time.time() - init_time

それは私が望むことだけを行いますが、オブジェクトをいじる代わりに、Deferred 構造が実行時間自体を追跡する何かを公開することを望んでいました。ソースコードから、そのようなものが利用できないことがわかります: http://twistedmatrix.com/trac/browser/tags/releases/twisted-10.0.0/twisted/internet/defer.py#L137

于 2010-10-28T11:32:27.970 に答える