1. 程式人生 > >Python中計時,看這一篇就夠了

Python中計時,看這一篇就夠了

計時對於瞭解程式的效能是很關鍵的部分。

本文討論了Python 2和python 3中計時方法,並完成了一個通用的計時裝飾器。

一、python2和python3的通用計時方法

由於python2和3裡面的計時函式是不一樣的,建議使用timeit模組中的timeit.default_timer()

由timeit.default_timer()的官方文件可知,計時時間精度和平臺以及使用的函式有關:

"Define a default timer, in a platform-specific manner. On Windows, time.clock() has microsecond granularity, but 

time.time()’s granularity is 1/60th of a second. On Unix, time.clock() has 1/100th of a second granularity, and time.time() is much more precise. On either platform, default_timer() measures wall clock time, not the CPU time. This means that other processes running on the same computer may interfere with the timing."

翻譯過來就是,

“定義在預設的計時器中,針對不同平臺採用不同方式。在Windows上,time.clock()具有微秒精度,但是time.time()精度是1/60s。在Unix上,time.clock()有1/100s精度,而且time.time()精度遠遠更高。在另外的平臺上,default_timer()測量的是牆上時鐘時間,不是CPU時間。這意味著同一計算機的其他程序可能影響計時。”

具體區別可以檢視python2和3中timeit的實現:

python2中:

if sys.platform == "win32":
    # On Windows, the best timer is time.clock()
    default_timer = time.clock
else:
    # On most other platforms the best timer is time.time()
    default_timer = time.time

python3中:

default_timer = time.perf_counter

再由time.clock()的官方文件可以看出:

"Deprecated since version 3.3: The behaviour of this function depends on the platform: use perf_counter() or process_time() instead, depending on your requirements, to have a well defined behaviour."

翻譯過來就是:

“python3.3版本後time.clock()就過時了:這個函式的行為受平臺影響,用time.perf_counter()”或者time.process_time()代替來得到一個定義更好的行為,具體取決於你的需求。”

更多詳細資訊請看官方文件中的time.get_clock_info()

二、方便使用的計時裝飾器

這一部分把計時函式寫成python的裝飾器形式,這樣使用的時候只要在函式的定義前面加上“@裝飾器名稱”即可。

具體實現和測試程式碼如下,參考了《Fluent Python》7.7節的相關內容,並參考本文第一部分改成了Python2和Python3通用的版本。

import time, timeit

def clock(func):
    def clocked(*args):
        t0 = timeit.default_timer()
        result = func(*args)
        elapsed = timeit.default_timer() - t0
        name = func.__name__
        arg_str = ', '.join(repr(arg) for arg in args)
        print('[%0.8fs] %s(%s) -> %r' % (elapsed, name, arg_str, result))
        return result
    return clocked

@clock
def run(seconds):
    time.sleep(seconds)
    return time

if __name__ == '__main__':
   run(1)

其中的run函式只是為了測試,可以換成其他你需要的函式。只要在前面加上@clock就可以了。