私の欲しいのは、コードのどこかで時間のカウントを開始してから経過時間を取得し、それがいくつかの関数の実行に要した時間を測定することです。私はtimeitモジュールを間違って使っていると思いますが、ドキュメントは私を混乱させるだけです。
import timeit
start = timeit.timeit()
print "hello"
end = timeit.timeit()
print end - start
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
(Thanks Amber )の使用を推奨していました。しかし、現在は非推奨です。
Unixでは、現在のプロセッサ時間を秒単位の浮動小数点数として返します。精度、そして実際には「プロセッサ時間」の意味の定義そのものは、同じ名前のC関数の精度に依存します。
Windowsでは、この関数は Win32関数
QueryPerformanceCounter()
に基づき、が最初にこの関数を呼び出してから経過したウォールクロック秒を浮動小数点数として返します。分解能は通常1マイクロ秒より優れています。バージョン3.3以降廃止予定:この関数の動作はプラットフォームによって異なります: 代わりに
perf_counter()
またはprocess_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()の正確性は?を参照してください。
また見なさい:
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
は、スリープ中に経過した時間を含みません。
あなたが時間を計りたいと思う機能を考えて、
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ステートメントを入れないでください。そうでなければ、測定される時間は 端末の速度 に依存します。
私はこれが好きです。 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
をプリントアウトに書き込んだだけです。
with
ブロックに入ったときに開始時間を自動的に記憶してからブロック終了時に終了時間をフリーズするコンテキストマネージャでこれを行うのは楽しいです。ちょっとしたトリックを使えば、同じcontext-manager関数からブロック内で実行中の経過時間の集計を取得することさえできます。
コアライブラリはこれを持っていません(しかしおそらくそうすべきです)。配置したら、次のようなことができます。
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秒)を返します。
time.time
を使用して実行を測定すると、コンピュータ上の他のプロセスが費やした実行時間を含む、コマンドの全体的な実行時間がわかります。それはユーザーが気づく時間ですが、あなたが別のコードスニペット/アルゴリズム/機能/を比較したいのであれば良くありません...
timeit
に関するさらに詳しい情報:
プロファイリングについてより深い洞察が必要な場合
更新 :昨年は http://pythonhosted.org/line_profiler/ を多用しましたが、Pythonsプロファイルモジュールの代わりにそれを使用することをお勧めします。
これは "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)
ダミーの例ではあまり効果がありませんが、何ができるかについてのアイデアをあなたに提供します。このアプローチの最も良いところは、これらの数値を取得して明らかにプロファイリングを手助けするために、私の既存のコードを編集する必要がないことです。
これはタイミングコードのための別のコンテキストマネージャです -
使用法:
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)
私はそれが非常に有益だと思った。
(Ipythonのみ) %timeit を使用して平均処理時間を測定できます。
def foo():
print "hello"
その後:
%timeit foo()
結果は次のようになります。
10000 loops, best of 3: 27 µs per loop
今は2019年です。簡潔な方法でやってみましょう:
from ttictoc import TicToc
t = TicToc() ## TicToc("name")
t.tic();
# your code ...
t.toc();
print(t.elapsed)
他の代わりにこのアプローチを使用する利点:
t = TicToc(nested=True)
t.tic()
some code1...
t.tic()
some code2...
t.tic()
some code3...
print(t.toc()) # Prints time for code 3
print(t.toc()) # Prints time for code 2 with code 3
print(t.toc()) # Prints time for code 1 with code 2 and 3
t = TicToc("save user")
print(t.name)
詳細な手順については、これを参照してください link .
python3上で:
from time import sleep, perf_counter as pc
t0 = pc()
sleep(1)
print(pc()-t0)
エレガントで短いです。
超遅い応答のようなものですが、多分それは誰かのための目的を果たします。これは私がスーパークリーンだと思うそれを行う方法です。
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")
"print"はPython 3の関数であり、Python 2.7の関数ではないことに注意してください。ただし、それは他のどの機能とも連動します。乾杯!
私はそれが好きですsimple(python 3):
from timeit import timeit
timeit(lambda: print("hello"))
1回の実行の出力はmicrosecondsです。
2.430883963010274
説明:timeitは匿名関数を実行します100万回デフォルトでは、結果はsecondsで与えられます。したがって、1回の実行の結果は同じ量ですが、平均でマイクロ秒です。
slow操作の場合、より少ないnumberの反復を追加するか、永遠に待機する可能性があります。
import time
timeit(lambda: time.sleep(1.5), number=1)
出力は、繰り返しの合計numberに対して常にsecondsにあります。
1.5015795179999714
時間を人間が読める時間に変換することもできます。
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')
ここに私の調査結果はここに多くのよい答えおよび他の少数の記事を経た後である。
まず、time.time
ではなくtimeit
を(そして多くの場合はperfカウンタAPIを)使用したいのです。
timeit
はあなたのOSとPythonのバージョンで利用可能な最良のタイマーを選択します。 timeit
はガベージコレクションを無効にしますが、これはあなたが望むかもしれないし望まないかもしれません。現在の問題は、timeitはセットアップが必要で、たくさんのインポートがあると醜いものになるので使いやすいということではありません。理想的には、デコレータが欲しい、またはwith
ブロックを使って時間を測定するだけです。残念ながら、これに利用できる組み込みのものは何もないので、私は小さなユーティリティモジュールの下に作成しました。
タイミングユーティリティモジュール
# utils.py
from functools import wraps
import gc
import timeit
def MeasureTime(f):
@wraps(f)
def _wrapper(*args, **kwargs):
gcold = gc.isenabled()
gc.disable()
start_time = timeit.default_timer()
try:
result = f(*args, **kwargs)
finally:
elapsed = timeit.default_timer() - start_time
if gcold:
gc.enable()
print('Function "{}": {}s'.format(f.__name__, elapsed))
return result
return _wrapper
class MeasureBlockTime:
def __init__(self,name="(block)", no_print = False, disable_gc = True):
self.name = name
self.no_print = no_print
self.disable_gc = disable_gc
def __enter__(self):
if self.disable_gc:
self.gcold = gc.isenabled()
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
を使用)。timeit を使用するもう1つの方法
from timeit import timeit
def func():
return 1 + 1
time = timeit(func, number=1)
print(time)
私はこれのためにライブラリを作りました、あなたが機能を測定したいならばあなたはちょうどこのようにそれをすることができます
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ノートブックにあるこれらの2行のコードを取り、Niceのインタラクティブなダイアグラムを生成します。例えば:
これがコードです。繰り返しますが、%
で始まる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ウェブサイト の詳細。
あなたは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
Functionにパラメータがなければラッパー関数は必要ありません。
測定時間 秒単位:
from timeit import default_timer as timer
from datetime import timedelta
start = timer()
end = timer()
print(timedelta(seconds=end-start))
私が考えることができる唯一の方法はtime.time()
を使うことです。
import time
start = time.time()
sleep(5) #just to give it some delay to show it working
finish = time.time()
elapsed = finish - start
print(elapsed)
それが役立つことを願っています。