ホーム テクノロジー 開発 非公開: Python Timeit を使用してコードの時間を計測する

Python Timeit を使用してコードの時間を計測する


このチュートリアルでは、Python の timeit モジュールの timeit 関数の使用方法を学びます。 Python で単純な式と関数の時間を計測する方法を学びます。

コードのタイミングを計測すると、コードの実行時間を見積もることができ、最適化が必要なコードのセクションを特定することもできます。

まず、Python のtimeit関数の構文を学習します。次に、Python モジュール内のコードと関数のブロックの時間を計測するためにこれを使用する方法を理解するためにコード例を示します。さぁ、始めよう。

Python timeit 関数の使用方法

timeitモジュールは Python 標準ライブラリの一部であり、インポートできます。

 import timeit

timeitモジュールからtimeit関数を使用する構文は次のとおりです。

 timeit.timeit(stmt, setup, number)

ここ:

  • stmtは、実行時間を測定するコード部分です。単純な Python 文字列または複数行の文字列として指定することも、呼び出し可能オブジェクトの名前を渡すこともできます。
  • 名前が示すように、 setupstmt実行するための前提条件として、1 回だけ実行する必要があるコード部分を示します。たとえば、NumPy 配列の作成の実行時間を計算しているとします。この場合、 numpyのインポートはsetupコードであり、実際の作成は時間を測定するステートメントです。
  • パラメータnumber stmtが実行される回数を示します。 numberのデフォルト値は 100 万 (1000000) ですが、このパラメータを任意の他の値に設定することもできます。

timeit()関数を使用する構文を学習したので、いくつかの例のコーディングを開始しましょう。

単純な Python 式のタイミング

タイミング-シンプル-Python-式
タイミング-シンプル-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 timeittimeitメインモジュールとして実行することを表します。
  • 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 に設定されます。これは、指定されたnumberstmtの実行が 5 回繰り返され、実行時間のうち最良のものが返されることを意味します。

timeit を使用した文字列反転メソッドの分析

Python 文字列を操作する場合、文字列を逆にしたい場合があります。文字列を反転する最も一般的な 2 つのアプローチは次のとおりです。

  • 文字列スライスの使用
  • reversed()関数とjoin()メソッドの使用
timeitを使用した文字列反転メソッドの分析
timeitを使用した文字列反転メソッドの分析

文字列スライスを使用して Python 文字列を反転する

文字列スライスの仕組みと、それを使用して Python 文字列を反転する方法を見てみましょう。構文some-string[start:stop]を使用すると、インデックスstartから始まりインデックスstop-1までの文字列のスライスが返されます。例を挙げてみましょう。

次の文字列「Python」について考えてみましょう。文字列の長さは 6 で、インデックスのリストは 0、1、2 から 5 までです。

画像-76
画像-76
 >>> string_1 = 'Python'

startstop値の両方を指定すると、 startからstop-1までにわたる文字列スライスが取得されます。したがって、 string_1[1:4] 「yth」を返します。

画像-77
画像-77
 >>> string_1 = 'Python'
>>> string_1[1:4]
'yth'

start値を指定しない場合、デフォルトのstart値 0 が使用され、スライスはインデックス 0 から始まりstop - 1まで拡張されます。

画像-78
画像-78

ここでは、 stop値は 3 であるため、スライスはインデックス 0 から始まり、インデックス 2 まで進みます。

 >>> string_1[:3]
'Pyt'

stopインデックスを含めない場合、スライスはstartインデックス (1) から始まり、文字列の終わりまで続くことがわかります。

画像-80
画像-80
 >>> string_1[1:]
'ython'

start値とstop値の両方を無視すると、文字列全体のスライスが返されます。

画像-81
画像-81
 >>> string_1[::]
'Python'

step値を使用してスライスを作成しましょう。 startstopstep値をそれぞれ 1、5、2 に設定します。 1 から始まり、2番目ごとの文字を含む 4 までの文字列のスライス (終点 5 を除く) を取得します。

画像-82
画像-82
 >>> string_1[1:5:2]
'yh'

負のステップを使用すると、文字列の終わりから始まるスライスを取得できます。ステップを -2 に設定すると、 string_1[5:2:-2]次のスライスを生成します。

画像-83
画像-83
 >>> string_1[5:2:-2]
'nh'

したがって、文字列の反転コピーを取得するには、次のようstartstop値をスキップし、ステップを -1 に設定します。

 >>> string_1[::-1]
'nohtyP'

要約すると、 string[::-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

次に、構文<sep>.join(reversed(some-string))使用して、逆反復子でjoin()メソッドを呼び出すことができます。

以下のコード スニペットは、区切り文字がそれぞれハイフンと空白であるいくつかの例を示しています。

 >>> '-'.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 式の時間を測定した前の例では、 setupコードがありませんでした。ここでは、Python 文字列を逆にしています。文字列反転操作は、 numberで指定された回数だけ実行されますが、 setupコードは 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()関数を使用するよりも高速です。

Python でリストを反転して逆方向にスピンする方法もお読みください。

timeit を使用した Python 関数のタイミング

タイミング-Python-関数-timeit の使用
タイミング-Python-関数-timeit の使用

このセクションでは、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()の呼び出しです。次に、セットアップコードを定義しましょう。 setupコードが何であるべきかわかりますか?

関数呼び出しを正常に実行するには、セットアップ コードに次のものが含まれている必要があります。

  • 関数の定義hasDigit()
  • 文字列の引数リストの初期化

以下に示すように、 setup文字列でセットアップ コードを定義しましょう。

 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 で時差を計算する方法を学びます。

「 Python Timeit を使用してコードの時間を計測する」についてわかりやすく解説!絶対に観るべきベスト2動画

【こつこつPython】Pythonで時間差の計算をする方法|datetime.timedelta
【こつこつPython】Pythonで時刻を扱う方法|datetime.time