Help us understand the problem. What is going on with this article?

time.time()は精度があまりよくない?

More than 3 years have passed since last update.

環境:win7 & blender2.77aのpython3.5.1

処理にかかった時間を調べる時

import time

start_time = time.time()

#
# 色々な処理
#

print(time.time() - start_time)

自分はよくこう書いていてました。
こう書いているのも良く見かけますし。
でも調べるたびに数値が結構変わることが多かったので不思議でした。

time.time()の精度

どの程度の精度があるのか。
timeitのドキュメントにこう書いてました。

http://docs.python.jp/2/library/timeit.html#timeit.default_timer

Windows の場合、 time.clock() はマイクロ秒の精度がありますが、 time.time() は 1/60 秒の精度しかありません。一方 Unixの場合、 time.clock() でも 1/100 秒の精度があり、 time.time() はもっと正確です。

Windowsだと1/60秒の精度しか無いようです。
これでは細かな時間は計れませんね・・・

他に時間を計測できる関数とか

time.clock()3.3で撤廃
time.monotonic()
time.perf_counter()
time.process_time()
めぼしいのはこのあたりのようです。

time.get_clock_info()をつかって情報を見る。

import time

print("clock:\n{}".format(time.get_clock_info('clock')))
print("monotonic:\n{}".format(time.get_clock_info('monotonic')))
print("perf_counter:\n{}".format(time.get_clock_info('perf_counter')))
print("process_time:\n{}".format(time.get_clock_info('process_time')))
print("time:\n{}".format(time.get_clock_info('time')))

出力結果

clock:
namespace(adjustable=False, implementation='QueryPerformanceCounter()',monotonic=True, resolution=6.984127871000365e-08)

monotonic:
namespace(adjustable=False, implementation='GetTickCount64()', monotonic=True, resolution=0.015600099999999999)

perf_counter:
namespace(adjustable=False, implementation='QueryPerformanceCounter()', monotonic=True, resolution=6.984127871000365e-08)

process_time:
namespace(adjustable=False, implementation='GetProcessTimes()', monotonic=True, resolution=1e-07)

time:
namespace(adjustable=True, implementation='GetSystemTimeAsFileTime()', monotonic=False, resolution=0.015600099999999999)

resolutionがクロックの分解能の秒数らしいので、値の小さいtime.perf_counter()time.process_time()を使うのがよさそうです。
time.time()を見ると確かに1/60秒ぐらいの精度しか無さそうです。

実際に計測

import time

start_time = time.perf_counter()
print("perf_counter = {:.7f}".format(time.perf_counter() - start_time))

start_time = time.process_time()
print("process_time = {:.7f}".format(time.process_time() - start_time))

出力結果

perf_counter = 0.0000029
process_time = 0.0000000

time.perf_counter()は期待通りの精度がありそうですね。time.process_time()は変ですね。
time.process_time()の分解能を調べてみます。

import time

time_list = []

time_list.append(time.process_time())
while len(time_list) < 5:
    next_time = time.process_time()
    if time_list[len(time_list)-1] != next_time:
        time_list.append(next_time)

print(time_list[1] - time_list[0])
print(time_list[2] - time_list[1])
print(time_list[3] - time_list[2])
print(time_list[4] - time_list[3])

出力結果

0.015600100000000339
0.015600100000000339
0.015600100000000339
0.015600100000000339

これを見るとどうやらtime.process_time()time.time()と同程度の分解能のようです。

結論

Windowsではtime.time()の精度はあまり高くなく、精度を求めるならtime.perf_counter()を使おうって事ですね。

takeopy
ホビープログラマ。主にPython、Go言語で遊んでます。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした