Pythonにコマンドラインプログラムがあり、完了するまでに時間がかかります。実行を終了するのにかかる正確な時間を知りたいです。
モジュールを見てきましたtimeit
が、それは小さなコードスニペット専用のようです。プログラム全体の時間を計りたいです。
Pythonにコマンドラインプログラムがあり、完了するまでに時間がかかります。実行を終了するのにかかる正確な時間を知りたいです。
モジュールを見てきましたtimeit
が、それは小さなコードスニペット専用のようです。プログラム全体の時間を計りたいです。
Pythonでの最も簡単な方法:
import time
start_time = time.time()
main()
print("--- %s seconds ---" % (time.time() - start_time))
これは、プログラムの実行に少なくとも10分の1秒かかることを前提としています。
プリント:
--- 0.764891862869 seconds ---
timing.py
このモジュールを自分のsite-packages
ディレクトリに置き、モジュールimport timing
の先頭に挿入します。
import atexit
from time import clock
def secondsToStr(t):
return "%d:%02d:%02d.%03d" % \
reduce(lambda ll,b : divmod(ll[0],b) + ll[1:],
[(t*1000,),1000,60,60])
line = "="*40
def log(s, elapsed=None):
print line
print secondsToStr(clock()), '-', s
if elapsed:
print "Elapsed time:", elapsed
print line
print
def endlog():
end = clock()
elapsed = end-start
log("End Program", secondsToStr(elapsed))
def now():
return secondsToStr(clock())
start = clock()
atexit.register(endlog)
log("Start Program")
timing.log
プログラム内に表示したい重要なステージがある場合は、プログラム内から呼び出すこともできます。ただし、含めるだけでimport timing
、開始時間と終了時間、および全体の経過時間が出力されます。(あいまいなsecondsToStr
関数を許してください。浮動小数点数の秒数を hh:mm:ss.sss 形式にフォーマットするだけです。)
LinuxまたはUnixの場合:
$ time python yourprogram.py
Windowsでは、次のStackOverflowの質問を参照してください:Windowsコマンドラインでコマンドの実行時間を測定するにはどうすればよいですか?
より詳細な出力については、
$ time -v python yourprogram.py
Command being timed: "python3 yourprogram.py"
User time (seconds): 0.08
System time (seconds): 0.02
Percent of CPU this job got: 98%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.10
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 9480
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 1114
Voluntary context switches: 0
Involuntary context switches: 22
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
モジュールが提供する出力が気に入っていますdatetime
。時間デルタ オブジェクトは、必要に応じて人間が読める方法で日、時間、分などを表示します。
例えば:
from datetime import datetime
start_time = datetime.now()
# do your work here
end_time = datetime.now()
print('Duration: {}'.format(end_time - start_time))
サンプル出力例
Duration: 0:00:08.309267
また
Duration: 1 day, 1:51:24.269711
JF Sebastian が述べたように、このアプローチは現地時間でいくつかのトリッキーなケースに遭遇する可能性があるため、使用する方が安全です。
import time
from datetime import timedelta
start_time = time.monotonic()
end_time = time.monotonic()
print(timedelta(seconds=end_time - start_time))
import time
start_time = time.clock()
main()
print(time.clock() - start_time, "seconds")
time.clock()
プロセッサ時間を返します。これにより、このプロセスで使用された時間のみを計算できます(とにかくUnixで)。ドキュメントには、「いずれにせよ、これはPythonまたはタイミングアルゴリズムのベンチマークに使用する関数です」と書かれています
私はPaul McGuireの回答が本当に好きですが、私はPython 3を使用しています。したがって、興味のある人のために、* nixでPython 3で動作する彼の回答の変更を次に示します(Windowsでは、clock()
の代わりに使用する必要があると思いますtime()
):
#python3
import atexit
from time import time, strftime, localtime
from datetime import timedelta
def secondsToStr(elapsed=None):
if elapsed is None:
return strftime("%Y-%m-%d %H:%M:%S", localtime())
else:
return str(timedelta(seconds=elapsed))
def log(s, elapsed=None):
line = "="*40
print(line)
print(secondsToStr(), '-', s)
if elapsed:
print("Elapsed time:", elapsed)
print(line)
print()
def endlog():
end = time()
elapsed = end-start
log("End Program", secondsToStr(elapsed))
start = time()
atexit.register(endlog)
log("Start Program")
これが役立つと思う場合は、彼がほとんどの作業を行ったので、これではなく彼の回答に賛成票を投じるべきです;)。
Python プロファイラー cProfile を使用してCPU 時間を測定し、さらに各関数内で費やされた時間と各関数が呼び出された回数を測定できます。これは、どこから始めればよいかわからないままスクリプトのパフォーマンスを改善したい場合に非常に便利です。別のスタックオーバーフローの質問に対するこの回答はかなり良いです. ドキュメントも参照することをお勧めします。
コマンド ラインから cProfile を使用してスクリプトをプロファイリングする方法の例を次に示します。
$ python -m cProfile euler048.py
1007 function calls in 0.061 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.061 0.061 <string>:1(<module>)
1000 0.051 0.000 0.051 0.000 euler048.py:2(<lambda>)
1 0.005 0.005 0.061 0.061 euler048.py:2(<module>)
1 0.000 0.000 0.061 0.061 {execfile}
1 0.002 0.002 0.053 0.053 {map}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler objects}
1 0.000 0.000 0.000 0.000 {range}
1 0.003 0.003 0.003 0.003 {sum}
時計()
バージョン 3.3 以降非推奨: この関数の動作はプラットフォームに依存します:要件に応じて、代わりにperf_counter()またはprocess_time()を使用して、明確に定義された動作を持たせてください。
time.perf_counter()
パフォーマンス カウンターの値 (小数秒単位) を返します。つまり、短い期間を測定するために使用できる最高の分解能を持つクロックです。スリープ中に経過した時間は含まれず、システム全体に適用されます。
time.process_time()
現在のプロセスのシステム CPU 時間とユーザー CPU 時間の合計の値 (小数秒単位) を返します。スリープ中に経過した時間は含まれません。
start = time.process_time()
... do something
elapsed = (time.process_time() - start)
Linux の場合はさらに優れています。time
$ time -v python rhtest2.py
Command being timed: "python rhtest2.py"
User time (seconds): 4.13
System time (seconds): 0.07
Percent of CPU this job got: 91%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:04.58
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 0
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 15
Minor (reclaiming a frame) page faults: 5095
Voluntary context switches: 27
Involuntary context switches: 279
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
次のスニペットは、人間が読める<HH:MM:SS>
形式で経過時間を出力します。
import time
from datetime import timedelta
start_time = time.time()
#
# Perform lots of computations.
#
elapsed_time_secs = time.time() - start_time
msg = "Execution took: %s secs (Wall clock time)" % timedelta(seconds=round(elapsed_time_secs))
print(msg)
Paul McGuire の回答も気に入り、私のニーズにより適したコンテキスト マネージャー フォームを思いつきました。
import datetime as dt
import timeit
class TimingManager(object):
"""Context Manager used with the statement 'with' to time some execution.
Example:
with TimingManager() as t:
# Code to time
"""
clock = timeit.default_timer
def __enter__(self):
"""
"""
self.start = self.clock()
self.log('\n=> Start Timing: {}')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""
"""
self.endlog()
return False
def log(self, s, elapsed=None):
"""Log current time and elapsed time if present.
:param s: Text to display, use '{}' to format the text with
the current time.
:param elapsed: Elapsed time to display. Dafault: None, no display.
"""
print s.format(self._secondsToStr(self.clock()))
if(elapsed is not None):
print 'Elapsed time: {}\n'.format(elapsed)
def endlog(self):
"""Log time for the end of execution with elapsed time.
"""
self.log('=> End Timing: {}', self.now())
def now(self):
"""Return current elapsed time as hh:mm:ss string.
:return: String.
"""
return str(dt.timedelta(seconds = self.clock() - self.start))
def _secondsToStr(self, sec):
"""Convert timestamp to h:mm:ss string.
:param sec: Timestamp.
"""
return str(dt.datetime.fromtimestamp(sec))
timeit
Python コードの実行時間を計測するために使用できるモジュールがあります。
Python ドキュメント26.6に詳細なドキュメントと例があります。timeit — 小さなコード スニペットの実行時間を測定します。