質問
私はただコードの時間を計ろうとしています。擬似コードは次のようになります。
start = get_ticks()
do_long_code()
print "It took " + (get_ticks() - start) + " seconds."
これはPythonでどのように見えますか?
より具体的には、真夜中以降のティック数を取得する方法(またはPythonがそのタイミングを整理する方法)
解決
time
モジュールには、 time
と clock
の2つのタイミング関数があります。 time
は" wall"を提供します時間、これがあなたが気にすることなら。
ただし、Python ドキュメントでは、 clock
ベンチマークに使用する必要があります。 clock
はシステムごとに異なる動作をすることに注意してください:
- MS Windowsでは、Win32関数のQueryPerformanceCounter()を使用します。「解像度は通常、マイクロ秒よりも優れています」。特別な意味はなく、単なる数字です(プロセスで
clock
を初めて呼び出したときにカウントを開始します)。
# ms windows t0= time.clock() do_something() t= time.clock() - t0 # t is wall seconds elapsed (floating point)
- * nixでは、
clock
はCPU時間を報告します。現在、これは異なり、おそらくあなたのプログラムがCPU時間を要求する唯一のプロセスではないので、おそらくあなたが望む値です(他のプロセスがなくても、カーネルは時々CPU時間を使用します)。したがって、この数値は通常は小さくなります¹ウォール時間(つまり、time.time()-t0)よりも、コードのベンチマークを行う場合に意味があります:
# linux t0= time.clock() do_something() t= time.clock() - t0 # t is CPU seconds elapsed (floating point)
それ以外にも、 timeit モジュールには Timer
利用可能な機能のベンチマークに最適なものを使用することになっているクラス。
¹スレッドが邪魔にならない限り…
² Python≥ 3.3: time.perf_counter()
および time.process_time()
。 perf_counter
は timeit
モジュールによって使用されています。
他のヒント
必要なのは、 time
モジュールの time()
関数です:
import time
start = time.time()
do_long_code()
print "it took", time.time() - start, "seconds."
その他のオプションについては、 timeit モジュールを使用できます。
最近使用し始めたソリューションは次のとおりです。
class Timer:
def __enter__(self):
self.begin = now()
def __exit__(self, type, value, traceback):
print(format_delta(self.begin, now()))
次のように使用します(少なくともPython 2.5が必要です):
with Timer():
do_long_code()
コードが終了すると、タイマーは実行時間を自動的に出力します。甘い! Pythonインタープリターで何かをすばやくベンチしようとする場合、これが最も簡単な方法です。
「now」と「format_delta」のサンプル実装を次に示しますが、お好みのタイミングとフォーマット方法を自由に使用してください。
import datetime
def now():
return datetime.datetime.now()
# Prints one of the following formats*:
# 1.58 days
# 2.98 hours
# 9.28 minutes # Not actually added yet, oops.
# 5.60 seconds
# 790 milliseconds
# *Except I prefer abbreviated formats, so I print d,h,m,s, or ms.
def format_delta(start,end):
# Time in microseconds
one_day = 86400000000
one_hour = 3600000000
one_second = 1000000
one_millisecond = 1000
delta = end - start
build_time_us = delta.microseconds + delta.seconds * one_second + delta.days * one_day
days = 0
while build_time_us > one_day:
build_time_us -= one_day
days += 1
if days > 0:
time_str = "%.2fd" % ( days + build_time_us / float(one_day) )
else:
hours = 0
while build_time_us > one_hour:
build_time_us -= one_hour
hours += 1
if hours > 0:
time_str = "%.2fh" % ( hours + build_time_us / float(one_hour) )
else:
seconds = 0
while build_time_us > one_second:
build_time_us -= one_second
seconds += 1
if seconds > 0:
time_str = "%.2fs" % ( seconds + build_time_us / float(one_second) )
else:
ms = 0
while build_time_us > one_millisecond:
build_time_us -= one_millisecond
ms += 1
time_str = "%.2fms" % ( ms + build_time_us / float(one_millisecond) )
return time_str
お好みのフォーマット方法がある場合、またはこれらすべてを行う簡単な方法がある場合はお知らせください!
Pythonの timeモジュールを使用すると、clock()にアクセスできます。浮動小数点として秒単位で時間を返す関数。
異なるシステムは、内部クロックの設定(1秒あたりのティック)に基づいて異なる精度を持ちますが、通常は少なくとも20ミリ秒未満であり、場合によっては数マイクロ秒よりも優れています。
-アダム
import datetime
start = datetime.datetime.now()
do_long_code()
finish = datetime.datetime.now()
delta = finish - start
print delta.seconds
深夜から:
import datetime
midnight = datetime.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
now = datetime.datetime.now()
delta = now - midnight
print delta.seconds
時間を計りたいステートメントが多数ある場合は、次のようなものを使用できます。
class Ticker:
def __init__(self):
self.t = clock()
def __call__(self):
dt = clock() - self.t
self.t = clock()
return 1000 * dt
その後、コードは次のようになります。
tick = Ticker()
# first command
print('first took {}ms'.format(tick())
# second group of commands
print('second took {}ms'.format(tick())
# third group of commands
print('third took {}ms'.format(tick())
この方法では、各ブロックの前に t = time()
を入力し、その後に 1000 *(time()-t)
を入力する必要はありません。フォーマットを制御します(ただし、 Ticket
に簡単に入れることもできます)。
最小限のゲインですが、便利だと思います。