1

2つのコードの実行時間を測定したいのですが、timeitのpythonドキュメントを調べてみましたが、よくわかりませんでした。誰かがより初心者レベルの語彙で説明できますか?

4

3 に答える 3

3

注: timeit モジュールの使用方法 にコピーされました。

秘密を教えましょうtimeit。コマンド ラインで使用するのが最適です。

コマンド ラインでtimeitは、適切な統計分析を行います。最短の実行にかかった時間を示します。タイミングのすべての誤差が正であるため、これは良いことです。したがって、最短時間には誤差が最も少なくなります。コンピューターが計算できる以上の速度で計算することはできないため、負のエラーを取得する方法はありません。

したがって、コマンドライン インターフェイスは次のようになります。

%~> python -m timeit "1 + 2"
10000000 loops, best of 3: 0.0468 usec per loop

それはとても簡単ですよね?

あなたはものを設定することができます:

%~> python -m timeit -s "x = range(10000)" "sum(x)"
1000 loops, best of 3: 543 usec per loop

これも便利です!

複数の行が必要な場合は、シェルの自動継続を使用するか、別の引数を使用できます。

%~> python -m timeit -s "x = range(10000)" -s "y = range(100)" "sum(x)" "min(y)"
1000 loops, best of 3: 554 usec per loop

それはのセットアップを与える

x = range(1000)
y = range(100)

と回

sum(x)
min(y)

timeitより長いスクリプトが必要な場合は、Python スクリプト内に移動したくなるかもしれません。コマンドラインの方が分析とタイミングが単純に優れているため、これは避けることをお勧めします。代わりに、シェル スクリプトを作成する傾向があります。

 SETUP="

 ... # lots of stuff

 "

 echo Minmod arr1
 python -m timeit -s "$SETUP" "Minmod(arr1)"

 echo pure_minmod arr1
 python -m timeit -s "$SETUP" "pure_minmod(arr1)"

 echo better_minmod arr1
 python -m timeit -s "$SETUP" "better_minmod(arr1)"

 ... etc

複数回の初期化により、これには少し時間がかかる場合がありますが、通常は大したことではありません。


しかし、モジュール内で使用したい場合はどうでしょうか?timeit

簡単な方法は次のとおりです。

def function(...):
    ...

timeit.Timer(function).timeit(number=NUMBER)

これにより、その回数を実行するための累積的な (最小ではありません!) 時間が得られます。

適切な分析を行うには、次の.repeat分を使用して取得します。

min(timeit.Timer(function).repeat(repeat=REPEATS, number=NUMBER))

通常、オーバーヘッドを下げるfunctools.partial代わりに、これを と組み合わせる必要があります。lambda: ...したがって、次のようなものがあります。

from functools import partial

def to_time(items):
    ...

test_items = [1, 2, 3] * 100
times = timeit.Timer(partial(to_time, test_items)).repeat(3, 1000)

# Divide by the number of repeats
time_taken = min(times) / 1000

次のこともできます。

timeit.timeit("...", setup="from __main__ import ...", number=NUMBER)

これにより、コマンドラインからのインターフェイスに近いものが得られますが、それほどクールではありません。"from __main__ import ..."によって作成された人工的な環境内で、メイン モジュールのコードを使用できますtimeit

これは の便利なラッパーでTimer(...).timeit(...)あり、タイミングが特に得意ではないことに注意してください。私は個人的に、上で示したように使用することをはるかに好みTimerます。


警告

timeitどこでも保持することにはいくつかの注意事項があります。

  • オーバーヘッドは考慮されていません。x += 1加算にかかる時間を調べるために time を使いたいとしましょう:

    >>> python -m timeit -s "x = 0" "x += 1"
    10000000 loops, best of 3: 0.0476 usec per loop
    

    ええと、0.0476 µsではありません。あなたはそれがそれ以下であることを知っているだけです。すべてのエラーは正です。

    したがって、純粋なオーバーヘッドを見つけてみてください。

    >>> python -m timeit -s "x = 0" ""      
    100000000 loops, best of 3: 0.014 usec per loop
    

    これは、タイミングだけで30%の優れたオーバーヘッドです! これにより、相対的なタイミングが大幅に歪む可能性があります。しかし、追加のタイミングだけが本当に気になりました。の検索タイミングxもオーバーヘッドに含める必要があります。

    >>> python -m timeit -s "x = 0" "x"
    100000000 loops, best of 3: 0.0166 usec per loop
    

    違いはそれほど大きくありませんが、そこにあります。

  • 変異方法は危険です。

    python -m timeit -s "x = [0]*100000" "while x: x.pop()"
    10000000 loops, best of 3: 0.0436 usec per loop
    

    しかし、それは完全に間違っています! x最初の反復後の空のリストです。再初期化する必要があります:

    >>> python -m timeit "x = [0]*100000" "while x: x.pop()"
    100 loops, best of 3: 9.79 msec per loop
    

    しかし、多くのオーバーヘッドがあります。その分は別途計上。

    >>> python -m timeit "x = [0]*100000"                   
    1000 loops, best of 3: 261 usec per loop
    

    ここでオーバーヘッドを差し引くことは合理的であることに注意してください。これはオーバーヘッドが時間のごく一部であるためです。

于 2013-09-21T17:33:09.273 に答える
0
>>> "-".join(str(n) for n in range(100))
'0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40-41-42-43-44-45-46-47-48-49-50-51-52-53-54-55-56-57-58-59-60-61-62-63-64-65-66-67-68-69-70-71-72-73-74-75-76-77-78-79-80-81-82-83-84-85-86-87-88-89-90-91-92-93-94-95-96-97-98-99'
>>> 

それが実行したいコマンドだとします。
インポートしtimeitます。コマンドを文字列にして、実行したい回数を追加します。

>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=100)
0.011214537887298093

ドキュメンテーション
このドキュメントは本当にわかりにくいですか? 私はそれが明快であると思います。

于 2013-09-21T17:21:57.403 に答える