このチュートリアルでは、Python の timeit モジュールから timeit 関数を使用する方法を学習します。 Python で単純な式と関数の時間を計測する方法を学習します。
コードのタイミングを計ると、コードの一部の実行時間の見積もりを取得したり、最適化が必要なコードのセクションを特定したりするのに役立ちます。
Python の timeit 関数の構文を学習することから始めます。 次に、コード例をコーディングして、それを使用して Python モジュールのコードと関数のブロックの時間を計る方法を理解します。 さぁ、始めよう。
Python timeit 関数の使用方法
timeit モジュールは Python 標準ライブラリの一部であり、インポートできます。
import timeit
timeit モジュールの timeit 関数を使用する構文は次のとおりです。
timeit.timeit(stmt, setup, number)
ここに:
- stmt は、実行時間を測定するコードです。 単純な Python 文字列または複数行の文字列として指定するか、callable の名前を渡すことができます。
- 名前が示すように、setup は、多くの場合、stmt を実行するための前提条件として、1 回だけ実行する必要があるコードの一部を示します。 たとえば、NumPy 配列の作成の実行時間を計算しているとします。 この場合、numpy のインポートはセットアップ コードであり、実際の作成は時間を計るステートメントです。
- パラメータ number は、stmt が実行される回数を示します。 number のデフォルト値は 100 万 (1000000) ですが、このパラメーターを任意の他の値に設定することもできます。
timeit() 関数を使用する構文を学習したので、いくつかの例のコーディングを開始しましょう。
単純な Python 式のタイミング
このセクションでは、timeit を使用して単純な Python 式の実行時間を測定してみます。
Python REPL を開始し、次のコード例を実行します。 ここでは、10000 回と 100000 回の実行に対するべき乗と床除算演算の実行時間を計算しています。
Python 文字列としてタイミングを取るステートメントを渡し、セミコロンを使用してステートメント内の異なる式を区切っていることに注意してください。
>>> import timeit >>> timeit.timeit('3**4;3//4',number=10000) 0.0004020999999738706 >>> timeit.timeit('3**4;3//4',number=100000) 0.0013780000000451764
コマンド ラインでの Python timeit の実行
コマンド ラインで timeit を使用することもできます。 timeit 関数呼び出しに相当するコマンド ラインを次に示します。
$ python-m timeit -n [number] -s [setup] [stmt]
- python -m timeit は、timeit をメイン モジュールとして実行することを表します。
- n は、コードを実行する回数を示すコマンド ライン オプションです。 これは、timeit() 関数呼び出しの number 引数に相当します。
- オプション -s を使用して、セットアップ コードを定義できます。
ここでは、同等のコマンドラインを使用して前の例を書き直します。
$ python -m timeit -n 100000 '3**4;3//4' 100000 loops, best of 5: 35.8 nsec per loop
この例では、組み込みの len() 関数の実行時間を計算します。 文字列の初期化は、s オプションを使用して渡されるセットアップ コードです。
$ python -m timeit -n 100000 -s "string_1 = 'coding'" 'len(string_1)' 100000 loops, best of 5: 239 nsec per loop
出力では、ベスト オブ 5 の実行の実行時間が取得されていることに注意してください。 これは何を意味するのでしょうか? コマンド ラインで timeit を実行すると、repeat オプション r がデフォルト値の 5 に設定されます。これは、指定された回数の stmt の実行が 5 回繰り返され、最良の実行時間が返されることを意味します。
timeit を使用した文字列反転メソッドの分析
Python 文字列を操作する場合、それらを逆にしたい場合があります。 文字列反転の最も一般的な 2 つの方法は次のとおりです。
- 文字列スライスの使用
- reversed() 関数と join() メソッドの使用
文字列スライスを使用した Python 文字列の反転
文字列スライスの仕組みと、それを使用して Python 文字列を逆にする方法について説明しましょう。 構文 some-string の使用[start:stop] インデックス start からインデックス stop-1 までの文字列のスライスを返します。 例を見てみましょう。
次の文字列「Python」を考えてみましょう。 文字列の長さは 6 で、インデックスのリストは 0、1、2 から 5 までです。
>>> string_1 = 'Python'
start 値と stop 値の両方を指定すると、start から stop-1 までの文字列スライスが得られます。 したがって、string_1[1:4] 「yth」を返します。
>>> string_1 = 'Python' >>> string_1[1:4] 'yth'
開始値を指定しない場合、デフォルトの開始値 0 が使用され、スライスはインデックス 0 から始まり、停止点 – 1 まで拡張されます。
ここでは、停止値が 3 であるため、スライスはインデックス 0 から始まり、インデックス 2 まで上がります。
>>> string_1[:3] 'Pyt'
停止インデックスを含めない場合、スライスは開始インデックス (1) から始まり、文字列の最後まで伸びていることがわかります。
>>> string_1[1:] 'ython'
start 値と stop 値の両方を無視すると、文字列全体のスライスが返されます。
>>> string_1[::] 'Python'
ステップ値でスライスを作成しましょう。 開始、停止、およびステップの値をそれぞれ 1、5、および 2 に設定します。 1 から始まり 4 まで (終点 5 を除く) までの文字列のスライスを取得します (終点 5 を除く)。
>>> string_1[1:5:2] 'yh'
負のステップを使用すると、文字列の最後から始まるスライスを取得できます。 ステップを -2 に設定すると、string_1[5:2:-2] 次のスライスを提供します。
>>> string_1[5:2:-2] 'nh'
したがって、文字列の逆コピーを取得するには、次のように、開始値と終了値をスキップし、ステップを -1 に設定します。
>>> string_1[::-1] 'nohtyP'
要約すると、文字列[::-1] 文字列の逆コピーを返します。
組み込み関数と文字列メソッドを使用した文字列の反転
Python の組み込みの reversed() 関数は、文字列の要素に対して逆方向反復子を返します。
>>> string_1 = 'Python' >>> reversed(string_1) <reversed object at 0x00BEAF70>
したがって、for ループを使用して逆イテレータをループできます。
for char in reversed(string_1): print(char)
逆の順序で文字列の要素にアクセスします。
# Output n o h t y P
次に、構文
以下のコード スニペットは、区切り文字がそれぞれハイフンと空白である 2 つの例を示しています。
>>> '-'.join(reversed(string1)) 'n-o-h-t-y-P' >>> ' '.join(reversed(string1)) 'n o h t y P'
ここでは、セパレーターは必要ありません。 そのため、セパレーターを空の文字列に設定して、文字列の逆コピーを取得します。
>>> ''.join(reversed(string1)) 'nohtyP'
”.join(reversed(some-string)) を使用すると、文字列の逆コピーが返されます。
timeit を使用した実行時間の比較
これまでのところ、Python 文字列を逆にする 2 つの方法を学びました。 しかし、どちらが速いですか? 確認してみましょう。
単純な Python 式の時間を測定した前の例では、セットアップ コードはありませんでした。 ここでは、Python 文字列を反転しています。 文字列反転操作は number で指定された回数実行されますが、セットアップ コードは、1 回だけ実行される文字列の初期化です。
>>> import timeit >>> timeit.timeit(stmt="string_1[::-1]", setup = "string_1 = 'Python'", number = 100000) 0.04951830000001678 >>> timeit.timeit(stmt = "''.join(reversed(string_1))", setup = "string_1 = 'Python'", number = 100000) 0.12858760000000302
指定された文字列を反転する実行回数が同じ場合、文字列スライス アプローチは、join() メソッドと reversed() 関数を使用するよりも高速です。
timeit を使用した Python 関数のタイミング
このセクションでは、timeit 関数を使用して Python 関数の時間を計る方法を学びましょう。 文字列のリストを指定すると、次の関数 hasDigit は、少なくとも 1 つの数字を含む文字列のリストを返します。
def hasDigit(somelist): str_with_digit = [] for string in somelist: check_char = [char.isdigit() for char in string] if any(check_char): str_with_digit.append(string) return str_with_digit
次に、timeit を使用して、この Python 関数 hasDigit() の実行時間を測定します。
最初に、時間を計測するステートメント (stmt) を特定しましょう。 文字列のリストを引数として関数 hasDigit() を呼び出します。 次に、セットアップ コードを定義しましょう。 セットアップコードがどうあるべきか推測できますか?
関数呼び出しを正常に実行するには、セットアップ コードに以下を含める必要があります。
- 関数 hasDigit() の定義
- 文字列の引数リストの初期化
以下に示すように、セットアップ文字列でセットアップ コードを定義しましょう。
setup = """ def hasDigit(somelist): str_with_digit = [] for string in somelist: check_char = [char.isdigit() for char in string] if any(check_char): str_with_digit.append(string) return str_with_digit thislist=['puffin3','7frost','blue'] """
次に、timeit 関数を使用して、100000 回の実行に対する hasDigit() 関数の実行時間を取得できます。
import timeit timeit.timeit('hasDigit(thislist)',setup=setup,number=100000)
# Output 0.2810094920000097
結論
Python の timeit 関数を使用して、式、関数、およびその他の呼び出し可能オブジェクトの時間を計測する方法を学習しました。 これは、コードのベンチマークを行ったり、同じ関数の異なる実装の実行時間を比較したりするのに役立ちます。
このチュートリアルで学んだことを復習しましょう。 timeit() 関数は、構文 timeit.timeit(stmt=…,setup=…,number=…) で使用できます。 または、コマンド ラインで timeit を実行して、短いコード スニペットの時間を計ることもできます。
次のステップとして、line-profiler や memprofiler などの他の Python プロファイリング パッケージを使用して、時間とメモリのそれぞれについてコードをプロファイリングする方法を調べることができます。
次に、Python で時差を計算する方法を学びます。