timeitを使用してPythonコードをプロファイリングする方法

設計上、Pythonはパフォーマンスよりも利便性、読みやすさ、使いやすさを優先しています。しかし、それはあなたが遅いPythonコードに落ち着くべきだという意味ではありません。それをスピードアップするためにあなたができることがおそらくあるでしょう。

Pythonコードのパフォーマンスをプロファイリングするために利用できるツールの中で、最も単純なのはtimeitモジュールです。timeitは、コードを数千回または数百万回実行し、それらの実行が完了するまでにかかった時間を報告することにより、コードの小さなスニペット(数行、関数)の速度を測定するために使用されます。

timeit何かをするための2つまたは3つの異なる方法を比較し、どれが最も速いかを確認するのに最も役立ちます。たとえば、何千回も繰り返されるループは、Pythonの一般的なボトルネックです。手書きのコードの代わりにPythonの組み込みコードを使用するなどして、そのループの実装を高速化する方法を見つけることができれば、パフォーマンスが大幅に向上する可能性があります。

簡単なPythontimeitの例

仕組みの簡単な例を次に示しtimeitます。

def f1():for n in range(100):pass def f2():n = 0 while n <100:n + = 1 if __name__ == "__main __":import timeit print(timeit.timeit(f1、number = 100000))print(timeit.timeit(f2、number = 100000)) 

このプログラムは、ループを100回反復する2つの方法のパフォーマンスを比較します。Pythonの組み込みrange 関数(f1)を使用する方法と 、変数をインクリメントする方法(f2)です。 timeit これらのアプローチのそれぞれを100,000回実行し、それぞれの最後に合計ランタイムを提供します。デフォルトでtimeit は、100万回の実行を使用します が、この例は、実行数を適切と思われる任意の数値に設定する方法を示しています。

結果(Intel i7-3770Kプロセッサーから):

0.1252315

0.45453989999999994

明らかに、この range アプローチははるかに高速で、約3.75倍です。これは驚くべきことではありません。Pythonビルトインを使用すると、通常、Pythonオブジェクトを手動で操作するよりもパフォーマンスが向上します。

文字列を渡してPythontimeitを使用する

使用する別の方法 timeit は、Pythonプログラムとして評価される文字列を渡すことです。

インポートtimeit

print(timeit.timeit( 'for n in range(100):pass'))

これは、コマンドラインからも実行できます。

python -m timeit "for n in range(100):pass"

ただし、全体として、コードをテキスト文字列にぎこちなく靴べらにする必要がないため、上記の手法を使用する方が簡単です。

Pythontimeitのヒント

そのままでも便利です timeit が、使用方法に関するこれらの警告に留意してください。

プログラム全体のプロファイリングにtimeitを使用しないでください

 プログラム全体の時間を 。で計ることができないとは何も言いませ timeit。たとえば、単純な10行のスクリプトは、この方法でプロファイリングするのに適した候補ではありません。

しかし、その仕事にはもっと優れたツールがあります。たとえば、Pythonの cProfile モジュールは、プログラム全体のパフォーマンスに関するはるかに詳細な統計を生成します。timeit 単一のコンポーネントまたはコードスニペットで最適に機能します—繰り返しになりますが、関数または数行のコードです。それ以上のものは、通常、ノイズが多すぎて一貫性がなく、意味のあるパフォーマンス情報を提供できない結果を生成します。

また、プロファイリングしているプログラムが完了するまでに何分もかかる場合は timeit 、あまり役に立ちません。1つは、コードを数回以上実行するのに時間がかかりすぎるため、収集されるタイミングが非常に粗雑になることです。2つ目は、他のツールの方が適しています。

異なるマシンで複数回実行する

プログラムは毎回同じ速度で実行されるわけではありません。最新のコンピューティング環境では、リソース、キャッシュの動作、スケジューリングなどについて他のプログラムとの競合など、多くの不確実性が生じます。 timeit コードを無限に実行することでこれを補おうとしますが、それでも複数の試行を集約することをお勧めします。timeit プロファイルを何度も実行し、最低スコアと最高スコアを捨て、残りを平均する必要があり ます。

最後に、異なるシステムで同じテストを実行することも役立ちます。ディスクにバインドされたものは、従来の回転ハードドライブと比較してSSDでどのように動作しますか?パフォーマンスに関する他の質問と同様に、推測しないでください。テストしてください。