回答:
2点間の経過時間を測定するだけの場合は、次を使用できます time.time()
。
import time
start = time.time()
print("hello")
end = time.time()
print(end - start)
これは、実行時間を秒単位で示します。
3.3以降のもう1つのオプションは、要件に応じてperf_counter
またはを使用process_time
することです。3.3より前は、使用することが推奨されていましたtime.clock
(アンバーに感謝します)。ただし、現在は非推奨です。
Unixでは、現在のプロセッサ時間を秒単位の浮動小数点数として返します。精度、および「プロセッサ時間」の意味の実際の定義は、同じ名前のC関数の精度に依存します。
Windowsでは、この関数は、Win32関数に基づいて、この関数を最初に呼び出してから経過した秒数を浮動小数点数として返します
QueryPerformanceCounter()
。解像度は通常、1マイクロ秒より優れています。バージョン3.3で非推奨:この関数の動作はプラットフォームによって異なります。要件に応じて、またはを使用する
perf_counter()
かprocess_time()
、動作を明確に定義してください。
time.clock()
システムクロックを用いて混乱取得した場合、それはに干渉することができないので、実際に、好ましいが、.time()
大部分は同じ目的を達成するん。)
print(timedelta(seconds=execution_time))
。別の質問ですが。
のtimeit.default_timer
代わりに使用しますtimeit.timeit
。前者は、プラットフォームとPythonのバージョンで利用可能な最高のクロックを自動的に提供します。
from timeit import default_timer as timer
start = timer()
# ...
end = timer()
print(end - start) # Time in seconds, e.g. 5.38091952400282
timeit.default_timerは、OSに応じてtime.time()またはtime.clock()に割り当てられます。Python 3.3以降では、すべてのプラットフォームでdefault_timerはtime.perf_counter()です。Python-time.clock()対time.time()-精度を参照してください。
以下も参照してください。
default_timer() measurations can be affected by other programs running on the same machine, so the best thing to do when accurate timing is necessary is to repeat the timing a few times and use the best time. The -r option is good for this; the default of 3 repetitions is probably enough in most cases. On Unix, you can use time.clock() to measure CPU time.
perf
モジュール(回答の時点では存在しない)にも関心があるかもしれませんが、時間のtimeit
パフォーマンスの測定方法に関するモジュールの決定と異なる場合があります。
time.clock()はPython 3.3で非推奨になっているtime.perf_counter()
ため、システム全体のタイミング、またはtime.process_time()
プロセス全体のタイミングに、以前と同じように使用することをお勧めしますtime.clock()
。
import time
t = time.process_time()
#do some stuff
elapsed_time = time.process_time() - t
新機能process_time
には、睡眠中の経過時間が含まれません。
timeit.default_timer
代わりに使用しますtime.perf_counter
。前者は、適切なタイマーを選択して、プラットフォームとPythonバージョンに合わせて調整された時間パフォーマンスを測定します。睡眠中の時間は含まれてprocess_time()
いないため、経過時間を測定することは適切ではありません。
あなたが時間を計りたい機能を与えられて、
test.py:
def foo():
# print "hello"
return "hello"
使用する最も簡単な方法timeit
は、コマンドラインから呼び出すことです。
% python -mtimeit -s'import test' 'test.foo()'
1000000 loops, best of 3: 0.254 usec per loop
関数の速度を比較するために、time.time
またはtime.clock
(単純に)を使用しないでください。彼らは誤解を招く結果を与えることができます。
PS。時間を計りたい関数にprintステートメントを入れないでください。そうでない場合、測定される時間は端末の速度に依存します。
これは、with
ブロックに入るときに開始時刻を自動的に記憶し、ブロックの終了時に終了時刻を固定するコンテキストマネージャで行うのが楽しいです。少しのトリックで、同じコンテキストマネージャー関数からブロック内で実行中の経過時間の集計を取得することもできます。
コアライブラリにはこれはありません(しかし、おそらくそうすべきです)。配置すると、次のようなことができます。
with elapsed_timer() as elapsed:
# some lengthy code
print( "midpoint at %.2f seconds" % elapsed() ) # time so far
# other lengthy code
print( "all done at %.2f seconds" % elapsed() )
ここだcontextmanagerのトリックを行うために十分なコードは:
from contextlib import contextmanager
from timeit import default_timer
@contextmanager
def elapsed_timer():
start = default_timer()
elapser = lambda: default_timer() - start
yield lambda: elapser()
end = default_timer()
elapser = lambda: end-start
そしていくつかの実行可能なデモコード:
import time
with elapsed_timer() as elapsed:
time.sleep(1)
print(elapsed())
time.sleep(2)
print(elapsed())
time.sleep(3)
この関数の設計により、の戻り値はelapsed()
ブロックの終了時に凍結され、以降の呼び出しは同じ期間(このおもちゃの例では約6秒)を返します。
私はこれが好きです。timeit
docはあまりにも混乱しています。
from datetime import datetime
start_time = datetime.now()
# INSERT YOUR CODE
time_elapsed = datetime.now() - start_time
print('Time elapsed (hh:mm:ss.ms) {}'.format(time_elapsed))
ここでは書式設定は行われていないことに注意してください。hh:mm:ss
印刷できるように書いたので、time_elapsed
これを行う別の方法を次に示します。
>> from pytictoc import TicToc
>> t = TicToc() # create TicToc instance
>> t.tic() # Start timer
>> # do something
>> t.toc() # Print elapsed time
Elapsed time is 2.612231 seconds.
従来の方法と比較:
>> from time import time
>> t1 = time()
>> # do something
>> t2 = time()
>> elapsed = t2 - t1
>> print('Elapsed time is %f seconds.' % elapsed)
Elapsed time is 2.612231 seconds.
インストール:
pip install pytictoc
詳細については、PyPiページを参照してください。
t.tic()
コードに埋もれていることに遭遇した場合、これがシリーズのどこにあると期待すべきかについてのメンタルリストを保持するのは開発者の責任です。自分で巣を作っているのか、それとも複数の目盛りを作っているのか?
ttictoc
。かなり混乱しましたが、今は問題ないはずです。
ここに、ここで多くの良い答えといくつかの他の記事を調べた後の私の発見があります。
まず、timeit
との間で議論している場合time.time
、にtimeit
は2つの利点があります。
timeit
OSとPythonのバージョンで利用できる最適なタイマーを選択します。 timeit
ガベージコレクションを無効にしますが、これは必要な場合もそうでない場合もあります。今問題は、timeit
設定が必要であり、大量のインポートがあると物事が醜くなるため、使用するのはそれほど簡単ではありません。理想的には、デコレータが必要か、with
ブロックを使用して時間を測定します。残念ながら、これに利用できるビルトインはないので、2つのオプションがあります。
オプション1:timebudgetライブラリを使用する
timebudgetはインストールピップ後ちょうど1行のコードで使用できる汎用性と非常にシンプルなライブラリです。
@timebudget # Record how long this function takes
def my_method():
# my code
オプション2:コードモジュールを直接使用する
以下の小さなユーティリティモジュールを作成しました。
# utils.py
from functools import wraps
import gc
import timeit
def MeasureTime(f, no_print=False, disable_gc=False):
@wraps(f)
def _wrapper(*args, **kwargs):
gcold = gc.isenabled()
if disable_gc:
gc.disable()
start_time = timeit.default_timer()
try:
result = f(*args, **kwargs)
finally:
elapsed = timeit.default_timer() - start_time
if disable_gc and gcold:
gc.enable()
if not no_print:
print('"{}": {}s'.format(f.__name__, elapsed))
return result
return _wrapper
class MeasureBlockTime:
def __init__(self,name="(block)", no_print=False, disable_gc=False):
self.name = name
self.no_print = no_print
self.disable_gc = disable_gc
def __enter__(self):
self.gcold = gc.isenabled()
if self.disable_gc:
gc.disable()
self.start_time = timeit.default_timer()
def __exit__(self,ty,val,tb):
self.elapsed = timeit.default_timer() - self.start_time
if self.disable_gc and self.gcold:
gc.enable()
if not self.no_print:
print('Function "{}": {}s'.format(self.name, self.elapsed))
return False #re-raise any exceptions
これで、関数の前にデコレータを置くだけで、任意の関数の時間を計ることができます。
import utils
@utils.MeasureTime
def MyBigFunc():
#do something time consuming
for i in range(10000):
print(i)
コードの一部の時間を計測したい場合は、with
ブロック内に配置します。
import utils
#somewhere in my code
with utils.MeasureBlockTime("MyBlock"):
#do something time consuming
for i in range(10000):
print(i)
# rest of my code
利点:
ハーフバックされたバージョンがいくつか浮かんでいるので、いくつかのハイライトを指摘したいと思います。
with utils.MeasureBlockTime() as t
次にを使用t.elapsed
)。を使用time.time
して実行を測定すると、コンピューター上の他のプロセスが費やした実行時間を含む、コマンドの全体的な実行時間がわかります。それはユーザーが気づくときですが、異なるコードスニペット/アルゴリズム/関数/ ...を比較したい場合は良くありません。
の詳細timeit
:
プロファイリングへのより深い洞察が必要な場合:
更新:昨年はhttp://pythonhosted.org/line_profiler/を頻繁に使用しましたが、Pythonのプロファイルモジュールの代わりに使用することをお勧めします。
以下は、 "hh:mm:ss"文字列を返す小さなタイマークラスです。
class Timer:
def __init__(self):
self.start = time.time()
def restart(self):
self.start = time.time()
def get_time_hhmmss(self):
end = time.time()
m, s = divmod(end - self.start, 60)
h, m = divmod(m, 60)
time_str = "%02d:%02d:%02d" % (h, m, s)
return time_str
使用法:
# Start timer
my_timer = Timer()
# ... do something
# Get time string:
time_hhmmss = my_timer.get_time_hhmmss()
print("Time elapsed: %s" % time_hhmmss )
# ... use the timer again
my_timer.restart()
# ... do something
# Get time:
time_hhmmss = my_timer.get_time_hhmmss()
# ... etc
python cProfileおよびpstatsモジュールは、既存の関数の周りにコードを追加する必要なしに、特定の関数の経過時間を測定するための優れたサポートを提供します。
たとえば、PythonスクリプトtimeFunctions.pyがある場合:
import time
def hello():
print "Hello :)"
time.sleep(0.1)
def thankyou():
print "Thank you!"
time.sleep(0.05)
for idx in range(10):
hello()
for idx in range(100):
thankyou()
プロファイラーを実行してファイルの統計を生成するには、次のように実行します。
python -m cProfile -o timeStats.profile timeFunctions.py
これは、cProfileモジュールを使用して、timeFunctions.py内のすべての関数をプロファイルし、timeStats.profileファイルに統計を収集することです。既存のモジュール(timeFunctions.py)にコードを追加する必要はなく、これはどのモジュールでも実行できることに注意してください。
statsファイルを取得したら、次のようにpstatsモジュールを実行できます。
python -m pstats timeStats.profile
これにより、多くの優れた機能を提供するインタラクティブな統計ブラウザが実行されます。特定のユースケースでは、関数の統計を確認できます。この例では、両方の関数の統計を確認すると、次のことがわかります。
Welcome to the profile statistics browser.
timeStats.profile% stats hello
<timestamp> timeStats.profile
224 function calls in 6.014 seconds
Random listing order was used
List reduced from 6 to 1 due to restriction <'hello'>
ncalls tottime percall cumtime percall filename:lineno(function)
10 0.000 0.000 1.001 0.100 timeFunctions.py:3(hello)
timeStats.profile% stats thankyou
<timestamp> timeStats.profile
224 function calls in 6.014 seconds
Random listing order was used
List reduced from 6 to 1 due to restriction <'thankyou'>
ncalls tottime percall cumtime percall filename:lineno(function)
100 0.002 0.000 5.012 0.050 timeFunctions.py:7(thankyou)
ダミーの例ではあまり効果はありませんが、何ができるかがわかります。このアプローチの最も良い点は、これらの数値を得るために既存のコードを編集する必要がなく、明らかにプロファイリングに役立つことです。
python -m pstats timeStats.profile ValueError: bad marshal data (unknown type code)
実行中のpythonバージョンを確認してください。私が走ったとき、私はこれを得たpython3 -m cProfile...
とpython -m pstats
。私の間違いですが、少しの間私を捕まえたので、私は共有したいと思いましたdon't forget consistency
。=)
タイミングコードの別のコンテキストマネージャーを次に示します。
使用法:
from benchmark import benchmark
with benchmark("Test 1+1"):
1+1
=>
Test 1+1 : 1.41e-06 seconds
または、時間値が必要な場合
with benchmark("Test 1+1") as b:
1+1
print(b.time)
=>
Test 1+1 : 7.05e-07 seconds
7.05233786763e-07
benchmark.py:
from timeit import default_timer as timer
class benchmark(object):
def __init__(self, msg, fmt="%0.3g"):
self.msg = msg
self.fmt = fmt
def __enter__(self):
self.start = timer()
return self
def __exit__(self, *args):
t = timer() - self.start
print(("%s : " + self.fmt + " seconds") % (self.msg, t))
self.time = t
http://dabeaz.blogspot.fr/2010/02/context-manager-for-timing-benchmarks.htmlから転載
プロファイラモジュールを使用します。それは非常に詳細なプロファイルを提供します。
import profile
profile.run('main()')
それは次のようなものを出力します:
5 function calls in 0.047 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.000 0.000 :0(exec)
1 0.047 0.047 0.047 0.047 :0(setprofile)
1 0.000 0.000 0.000 0.000 <string>:1(<module>)
0 0.000 0.000 profile:0(profiler)
1 0.000 0.000 0.047 0.047 profile:0(main())
1 0.000 0.000 0.000 0.000 two_sum.py:2(twoSum)
私はそれが非常に有益であることを発見しました。
main()
?簡単なコード例を提供できれば、もっと便利でしょう。
私はそれがシンプルなのが好きです(python 3):
from timeit import timeit
timeit(lambda: print("hello"))
1回の実行の出力はマイクロ秒です。
2.430883963010274
説明:timeitは、デフォルトで匿名関数を100万回実行し、結果は秒単位で示されます。したがって、1回の実行の結果は同じ量ですが、平均でマイクロ秒単位です。
以下のために遅い操作下に追加の数の反復をかあなたは永遠に待っていることができます:
import time
timeit(lambda: time.sleep(1.5), number=1)
出力は常にある秒合計数の反復:
1.5015795179999714
(Ipythonのみ)%timeitを使用して平均処理時間を測定できます。
def foo():
print "hello"
その後:
%timeit foo()
結果は次のようになります。
10000 loops, best of 3: 27 µs per loop
非常に遅い応答のようなものですが、おそらく誰かの目的に役立ちます。これは私がとてもきれいだと思う方法です。
import time
def timed(fun, *args):
s = time.time()
r = fun(*args)
print('{} execution took {} seconds.'.format(fun.__name__, time.time()-s))
return(r)
timed(print, "Hello")
「印刷」はPython 3の関数であり、Python 2.7の関数ではないことに注意してください。ただし、他の機能と連携します。乾杯!
timeitを使用できます。
Python REPLを使用してパラメーターを取るnaive_funcをテストする方法の例を次に示します。
>>> import timeit
>>> def naive_func(x):
... a = 0
... for i in range(a):
... a += i
... return a
>>> def wrapper(func, *args, **kwargs):
... def wrapper():
... return func(*args, **kwargs)
... return wrapper
>>> wrapped = wrapper(naive_func, 1_000)
>>> timeit.timeit(wrapped, number=1_000_000)
0.4458435332577161
関数にパラメーターがない場合、ラッパー関数は必要ありません。
lambda
はより簡潔です:print(timeit.timeit(lambda: naive_func(1_000), number=1_000_000))
時間を人間が読める時間に変換することもできます。
import time, datetime
start = time.clock()
def num_multi1(max):
result = 0
for num in range(0, 1000):
if (num % 3 == 0 or num % 5 == 0):
result += num
print "Sum is %d " % result
num_multi1(1000)
end = time.clock()
value = end - start
timestamp = datetime.datetime.fromtimestamp(value)
print timestamp.strftime('%Y-%m-%d %H:%M:%S')
私はこれのためのライブラリを作りました、あなたが関数を測定したいなら、あなたはこのようにそれをすることができます
from pythonbenchmark import compare, measure
import time
a,b,c,d,e = 10,10,10,10,10
something = [a,b,c,d,e]
@measure
def myFunction(something):
time.sleep(0.4)
@measure
def myOptimizedFunction(something):
time.sleep(0.2)
myFunction(input)
myOptimizedFunction(input)
%load_ext snakeviz
%%snakeviz
Jupyter Notebook でこれらの2行のコードを使用するだけで、優れたインタラクティブな図が生成されます。例えば:
これがコードです。この場合も、先頭の2行%
は、snakevizを使用するために必要な追加のコード行のみです。
# !pip install snakeviz
%load_ext snakeviz
import glob
import hashlib
%%snakeviz
files = glob.glob('*.txt')
def print_files_hashed(files):
for file in files:
with open(file) as f:
print(hashlib.md5(f.read().encode('utf-8')).hexdigest())
print_files_hashed(files)
ノートブックの外でsnakevizを実行することも可能のようです。snakevizのウェブサイトで詳細をご覧ください。
このユニークなクラスベースのアプローチは、印刷可能な文字列表現、カスタマイズ可能な丸め、および文字列または浮動小数点数としての経過時間への便利なアクセスを提供します。Python 3.7で開発されました。
import datetime
import timeit
class Timer:
"""Measure time used."""
# Ref: https://stackoverflow.com/a/57931660/
def __init__(self, round_ndigits: int = 0):
self._round_ndigits = round_ndigits
self._start_time = timeit.default_timer()
def __call__(self) -> float:
return timeit.default_timer() - self._start_time
def __str__(self) -> str:
return str(datetime.timedelta(seconds=round(self(), self._round_ndigits)))
使用法:
# Setup timer
>>> timer = Timer()
# Access as a string
>>> print(f'Time elapsed is {timer}.')
Time elapsed is 0:00:03.
>>> print(f'Time elapsed is {timer}.')
Time elapsed is 0:00:04.
# Access as a float
>>> timer()
6.841332235
>>> timer()
7.970274425
時間の単位:floatとして秒単位で測定
import timeit
t = timeit.Timer('li = list(map(lambda x:x*2,[1,2,3,4,5]))')
t.timeit()
t.repeat()
>[1.2934070999999676, 1.3335035000000062, 1.422568500000125]
repeat()メソッドは、timeit()を複数回呼び出して結果のリストを返すのに便利です。
repeat(repeat=3)¶
このリストを使用して、すべての時間の平均を取ることができます。
デフォルトでは、timeit()はタイミング中にガベージコレクションを一時的にオフにします。time.Timer()はこの問題を解決します。
長所:
timeit.Timer()は、独立したタイミングをより比較可能にします。gcは、測定される関数のパフォーマンスの重要なコンポーネントである可能性があります。その場合、セットアップ文字列の最初のステートメントとしてgc(ガベージコレクター)を再度有効にできます。例えば:
timeit.Timer('li = list(map(lambda x:x*2,[1,2,3,4,5]))',setup='gc.enable()')
ソースPythonドキュメント!
関数のタイミングを便利にしたい場合は、シンプルなデコレータを使用できます。
def timing_decorator(func):
def wrapper(*args, **kwargs):
start = time.time()
original_return_val = func(*args, **kwargs)
end = time.time()
print("time elapsed in ", func.__name__, ": ", end - start, sep='')
return original_return_val
return wrapper
あなたはこのように時間を計りたい関数でそれを使うことができます:
@timing_decorator
def function_to_time():
time.sleep(1)
その後、を呼び出すたびに、かかった時間と時間をfunction_to_time
計られている関数の名前が出力されます。
E731に従ってflake8がラムダの使用について警告するため、https: //stackoverflow.com/a/30024601/5095636で提供されているcontextmanagerソリューションに基づいて、ラムダの無料バージョンを提供します。
from contextlib import contextmanager
from timeit import default_timer
@contextmanager
def elapsed_timer():
start_time = default_timer()
class _Timer():
start = start_time
end = default_timer()
duration = end - start
yield _Timer
end_time = default_timer()
_Timer.end = end_time
_Timer.duration = end_time - start_time
テスト:
from time import sleep
with elapsed_timer() as t:
print("start:", t.start)
sleep(1)
print("end:", t.end)
t.start
t.end
t.duration
操作の継続時間を計算する最も簡単な方法:
import time
start_time = time.time()
print(time.ctime())
<operations, programs>
print('minutes: ',(time.time() - start_time)/60)
これは、私が一般的なユーティリティとして使用する、かなりよく文書化され、完全に型指定されたヒント付きデコレータです。
from functools import wraps
from time import perf_counter
from typing import Any, Callable, Optional, TypeVar, cast
F = TypeVar("F", bound=Callable[..., Any])
def timer(prefix: Optional[str] = None, precision: int = 6) -> Callable[[F], F]:
"""Use as a decorator to time the execution of any function.
Args:
prefix: String to print before the time taken.
Default is the name of the function.
precision: How many decimals to include in the seconds value.
Examples:
>>> @timer()
... def foo(x):
... return x
>>> foo(123)
foo: 0.000...s
123
>>> @timer("Time taken: ", 2)
... def foo(x):
... return x
>>> foo(123)
Time taken: 0.00s
123
"""
def decorator(func: F) -> F:
@wraps(func)
def wrapper(*args: Any, **kwargs: Any) -> Any:
nonlocal prefix
prefix = prefix if prefix is not None else f"{func.__name__}: "
start = perf_counter()
result = func(*args, **kwargs)
end = perf_counter()
print(f"{prefix}{end - start:.{precision}f}s")
return result
return cast(F, wrapper)
return decorator
使用例:
from timer import timer
@timer(precision=9)
def takes_long(x: int) -> bool:
return x in (i for i in range(x + 1))
print(takes_long(10**8))
出力:
takes_long: 4.942629056s True
doctestは以下で確認できます:
$ python3 -m doctest --verbose -o=ELLIPSIS timer.py
そして型は次のことを示唆します:
$ mypy timer.py
Callable[[AnyF], AnyF]
。どういう意味ですか?
AnyF
を意味するCallable[..., Any]
ように定義したのでAnyF
、任意の量の型引数を取り、何でも返すことができる関数です。したがって、Callable[[AnyF], AnyF]
に拡張されCallable[[Callable[..., Any]], Callable[..., Any]]
ます。これは、timer
の完全な型の別名の戻り値の型ですdecorator
。これは、あらゆる種類の関数を唯一の引数として取り、あらゆる種類の関数を返す関数です。