Berikut ini adalah temuan saya setelah melalui banyak jawaban yang baik di sini dan juga beberapa artikel lainnya.
Pertama, jika Anda berdebat antara timeit
dan time.time
, timeit
ada dua keuntungan:
timeit
pilih timer terbaik yang tersedia di OS dan versi Python Anda.
timeit
menonaktifkan pengumpulan sampah, namun, ini bukan sesuatu yang Anda mungkin atau mungkin tidak inginkan.
Sekarang masalahnya adalah timeit
tidak sesederhana itu untuk digunakan karena membutuhkan pengaturan dan hal-hal menjadi jelek ketika Anda memiliki banyak impor. Idealnya, Anda hanya ingin dekorator atau menggunakan with
blok dan mengukur waktu. Sayangnya, tidak ada built-in yang tersedia untuk ini sehingga Anda memiliki dua opsi:
Opsi 1: Gunakan perpustakaan timebudget
The timebudget adalah perpustakaan serbaguna dan sangat sederhana yang dapat Anda gunakan hanya dalam satu baris kode setelah pip install.
@timebudget # Record how long this function takes
def my_method():
# my code
Opsi 2: Gunakan modul kode secara langsung
Saya buat di bawah ini sedikit modul utilitas.
# 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
Sekarang Anda dapat mengatur waktu fungsi apa pun hanya dengan meletakkan dekorator di depannya:
import utils
@utils.MeasureTime
def MyBigFunc():
#do something time consuming
for i in range(10000):
print(i)
Jika Anda ingin waktu bagian kode maka cukup taruh di dalam with
blok:
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
Keuntungan:
Ada beberapa versi setengah didukung yang beredar jadi saya ingin menunjukkan beberapa highlight:
- Gunakan timer dari timeit bukan time.time karena alasan yang dijelaskan sebelumnya.
- Anda dapat menonaktifkan GC selama penghitungan waktu jika diinginkan.
- Dekorator menerima fungsi dengan param bernama atau tidak disebutkan namanya.
- Kemampuan untuk menonaktifkan pencetakan dalam waktu blok (gunakan
with utils.MeasureBlockTime() as t
dan kemudian t.elapsed
).
- Kemampuan untuk menjaga gc diaktifkan untuk timing blok.