Dưới đây là những phát hiện của tôi sau khi trải qua nhiều câu trả lời tốt ở đây cũng như một vài bài viết khác.
Đầu tiên, nếu bạn đang tranh luận giữa timeit
và time.time
, timeit
có hai ưu điểm:
timeit
chọn bộ hẹn giờ tốt nhất có sẵn trên phiên bản HĐH và Python của bạn.
timeit
vô hiệu hóa bộ sưu tập rác, tuy nhiên, đây không phải là thứ bạn có thể muốn hoặc không muốn.
Bây giờ vấn đề là nó timeit
không đơn giản để sử dụng vì nó cần thiết lập và mọi thứ trở nên xấu xí khi bạn có một loạt các nhập khẩu. Lý tưởng nhất, bạn chỉ muốn một trang trí hoặc sử dụngwith
khối và đo thời gian. Thật không may, không có gì tích hợp sẵn cho việc này để bạn có hai tùy chọn:
Tùy chọn 1: Sử dụng thư viện thời gian
Bảng thời gian là một thư viện linh hoạt và rất đơn giản mà bạn có thể sử dụng chỉ trong một dòng mã sau khi cài đặt pip.
@timebudget # Record how long this function takes
def my_method():
# my code
Tùy chọn 2: Sử dụng mô-đun mã trực tiếp
Tôi đã tạo ra bên dưới mô-đun tiện ích nhỏ.
# utils.py
from functools import wraps
import gc
import timeit
def MeasureTime(f, no_print=False, disable_gc=False):
@wraps(f)
def _wrapper(*args, **kwargs):
gcold = gc.isenabled()
if disable_gc:
gc.disable()
start_time = timeit.default_timer()
try:
result = f(*args, **kwargs)
finally:
elapsed = timeit.default_timer() - start_time
if disable_gc and gcold:
gc.enable()
if not no_print:
print('"{}": {}s'.format(f.__name__, elapsed))
return result
return _wrapper
class MeasureBlockTime:
def __init__(self,name="(block)", no_print=False, disable_gc=False):
self.name = name
self.no_print = no_print
self.disable_gc = disable_gc
def __enter__(self):
self.gcold = gc.isenabled()
if self.disable_gc:
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
Bây giờ bạn có thể đặt thời gian cho bất kỳ chức năng nào chỉ bằng cách đặt một trang trí trước nó:
import utils
@utils.MeasureTime
def MyBigFunc():
#do something time consuming
for i in range(10000):
print(i)
Nếu bạn muốn phần thời gian của mã thì chỉ cần đặt nó vào trong with
khối:
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
Ưu điểm:
Có một số phiên bản được hỗ trợ một nửa nổi xung quanh vì vậy tôi muốn chỉ ra một vài điểm nổi bật:
- Sử dụng bộ đếm thời gian từ timeit thay vì time.time vì những lý do được mô tả trước đó.
- Bạn có thể vô hiệu hóa GC trong thời gian nếu bạn muốn.
- Decorator chấp nhận các chức năng với các thông số được đặt tên hoặc không tên.
- Khả năng vô hiệu hóa in trong thời gian khối (sử dụng
with utils.MeasureBlockTime() as t
và sau đó t.elapsed
).
- Khả năng giữ gc kích hoạt cho thời gian khối.