2013-08-14 1 views
10

私は優秀なline_profilerを使用したいと思いますが、時のほんの一部です。それを動作させるには、すべての関数呼び出しの前に、例えば、line_profilerを使用したpythonプロファイリング - オンザフライで@profile文を削除する巧妙な方法?

@profile 

の前に追加します。

@profile 
def myFunc(args): 
    blah 
    return 

kernprof.py -l -v mycode.py args 

を実行する。しかし、ほとんどの時間は、私はそれらなしでコードを実行したいので、私は、手で毎回@profileデコレータを入れてしたくない、と私はそれらを含めると、例外が発生します。

mycode.py args 

私は動的にあまりにも多くの各機能を手動で物事を行う、および/または変更することなく、いくつかの条件スイッチ/引数に基づいて削除デコレータを持つことができる幸せな媒体がありますか?

+0

このようなサポートが必要となるほど頻繁にプロファイルを作成する必要があるかどうかは自問です。私はあなたがしているかしていないと言っているわけではないので、あなたは答える必要はありません。私はちょうど少し驚くべきユースケースを見つけました。 – msw

+0

コードの実行には時間がかかります(現時点では時間がかかります...)ので、今は結果とプロファイリングを同時に行うために2つの鳥を1つの石で殺したいと思います。私はプロファイリングを進行中のプロセスとして見ていると思います(私はそれが初めてで/興奮しています)ので、(多くの)関数で使用するだけでなく、宣言してすべてのデコレータを削除します。 – jtlz2

+0

私は[*試していない]何時間もかかることはありません(http://stackoverflow.com/a/4299378/23771)。それは何の費用もなく、何が起こっているかを正確に伝えます。 –

答えて

13

の代わりに@profileのデコレータラインを削除するには、パススルーno-opバージョンを用意してください。 @profileデコレータを使用して、この任意のコードの前に

import __builtin__ 

try: 
    __builtin__.profile 
except AttributeError: 
    # No line profiler, provide a pass-through version 
    def profile(func): return func 
    __builtin__.profile = profile 

インポート]を、あなたがアクティブであることで、ラインプロファイラーなしコードを使用することができます。

あなたはどこかにあなたのプロジェクトに次のコードを追加することができます。

ダミーデコレータはパススルー機能であるため、実行パフォーマンスには影響しません(インポートパフォーマンスはが影響を受けるたびにになります)。

組み込み機能を使いこなすのが気に入らない場合は、別のモジュールにすることができます。

import __builtin__ 

try: 
    profile = __builtin__.profile 
except AttributeError: 
    # No line profiler, provide a pass-through version 
    def profile(func): return func 

(ない割り当て__builtin__.profileから)と@profileデコレータを使用して任意のモジュールでfrom profile_support import profileを使用します。profile_support.py言いません。

+0

すごく感謝しています。私は第二の選択肢に行きました、そして、それはすばらしく動作します。 – jtlz2

+1

Python3では、 '__builtin__'を組み込み関数に置き換える必要があります。しかし、これは単なる検索と置き換えであり、他のすべては同じように機能します。 –

1

私は、Python 3.4

try: 
    import builtins 
    profile = builtins.__dict__['profile'] 
except KeyError: 
    # No line profiler, provide a pass-through version 
    def profile(func): return func 
3

@Martijinピータースの答えのバリアントに成長したコメントを、次の修正版を使用しています。

私は__builtin__をまったく含まないことを好みます。コメントをすれば、他人がこれを知っていることを事前に知らずに、line_profilerが関与していると推測することは事実上不可能です。

kernprofline 199を見ると、LineProfilerをインスタンス化するだけで十分です。グローバル(暗黙)builtinsを変更するより

try: 
    from line_profiler import LineProfiler 
    profile = LineProfiler() 
except ImportError: 
    def profile(func): 
     return func 

インポート(明示的)is better。プロファイリングデコレータが永続的である場合、その起源はコード自体で明確になるはずです。

line_profilerが存在する場合、上記の方法は、kernprofによって実行されるかどうかにかかわらず、すべての実行でプロファイラーで装飾された機能をラップします。この副作用は望ましくないかもしれません。

3

あなたはprofileを検索しようとしたとき、あなたは、単にNameErrorに頼ることができる、全く__builtins__/builtinsまたはLineProfilerをインポートする必要はありません。

try: 
    profile 
except NameError: 
    profile = lambda x: x 

しかしこれは、使用するすべてのファイルに含まれる必要がありますprofileしかし、(永久に)Pythonのグローバルな状態(組み込み関数)を変更するものではありません。

関連する問題