我想测量执行一个函数所花费的时间。我没时间工作:
import timeit
start = timeit.timeit()
print("hello")
end = timeit.timeit()
print(end - start)
我想测量执行一个函数所花费的时间。我没时间工作:
import timeit
start = timeit.timeit()
print("hello")
end = timeit.timeit()
print(end - start)
当前回答
如果您想方便地对函数计时,可以使用一个简单的修饰符:
import time
def timing_decorator(func):
def wrapper(*args, **kwargs):
start = time.perf_counter()
original_return_val = func(*args, **kwargs)
end = time.perf_counter()
print("time elapsed in ", func.__name__, ": ", end - start, sep='')
return original_return_val
return wrapper
您可以在您希望计时的函数上使用它,如下所示:
@timing_decorator
def function_to_time():
time.sleep(1)
function_to_time()
无论何时调用function_to_time,它都会打印所用的时间和正在计时的函数的名称。
其他回答
如果您想方便地对函数计时,可以使用一个简单的修饰符:
import time
def timing_decorator(func):
def wrapper(*args, **kwargs):
start = time.perf_counter()
original_return_val = func(*args, **kwargs)
end = time.perf_counter()
print("time elapsed in ", func.__name__, ": ", end - start, sep='')
return original_return_val
return wrapper
您可以在您希望计时的函数上使用它,如下所示:
@timing_decorator
def function_to_time():
time.sleep(1)
function_to_time()
无论何时调用function_to_time,它都会打印所用的时间和正在计时的函数的名称。
仅Python 3:
由于从Python 3.3开始,time.cclock()已被弃用,因此您将希望使用time.perf_counter()进行系统范围的计时,或使用time.process_time()进行进程范围的计时(就像您以前使用time.cclok()的方式一样):
import time
t = time.process_time()
#do some stuff
elapsed_time = time.process_time() - t
新函数process_time将不包括睡眠期间经过的时间。
基于https://stackoverflow.com/a/30024601/5095636,以下为无lambda版本,如flake8根据E731对lambda使用的警告:
from contextlib import contextmanager
from timeit import default_timer
@contextmanager
def elapsed_timer():
start_time = default_timer()
class _Timer():
start = start_time
end = default_timer()
duration = end - start
yield _Timer
end_time = default_timer()
_Timer.end = end_time
_Timer.duration = end_time - start_time
测试:
from time import sleep
with elapsed_timer() as t:
print("start:", t.start)
sleep(1)
print("end:", t.end)
t.start
t.end
t.duration
以下是我在阅读了许多好答案以及其他几篇文章之后的发现。
首先,如果你在timeit和time.time之间进行辩论,timeit有两个优点:
timeit选择操作系统和Python版本上可用的最佳计时器。然而,timeit禁用垃圾收集,这不是您可能想要或不想要的。
现在的问题是,时间并不是那么简单,因为它需要设置,当你有大量的导入时,事情会变得很糟糕。理想情况下,您只需要一个装饰器或使用块和度量时间。不幸的是,没有内置功能可用于此,因此您有两个选项:
选项1:使用时间预算库
timebudget是一个多功能且非常简单的库,您可以在pip安装后仅在一行代码中使用它。
@timebudget # Record how long this function takes
def my_method():
# my code
选项2:使用我的小模块
我创建了一个名为timing.py的计时实用程序模块。只需将这个文件放到项目中并开始使用它。唯一的外部依赖是runstats,它同样很小。
现在,只需在函数前面放置一个装饰器,就可以对任何函数计时:
import timing
@timing.MeasureTime
def MyBigFunc():
#do something time consuming
for i in range(10000):
print(i)
timing.print_all_timings()
如果您想对代码的一部分计时,只需将其放入块中:
import timing
#somewhere in my code
with timing.MeasureBlockTime("MyBlock"):
#do something time consuming
for i in range(10000):
print(i)
# rest of my code
timing.print_all_timings()
优势:
有几个半备份版本,所以我想指出几个亮点:
出于前面描述的原因,请使用timeit中的计时器,而不是time.time。如果需要,可以在计时期间禁用GC。Decorator接受带有命名或未命名参数的函数。能够在块计时中禁用打印(与timing.MeasureBlockTime()一起使用为t,然后为t.passed)。能够为块计时启用gc。
python cProfile和pstats模块为测量某些函数的时间提供了强大的支持,而无需在现有函数周围添加任何代码。
例如,如果您有python脚本timeFunctions.py:
import time
def hello():
print "Hello :)"
time.sleep(0.1)
def thankyou():
print "Thank you!"
time.sleep(0.05)
for idx in range(10):
hello()
for idx in range(100):
thankyou()
要运行探查器并生成文件的统计信息,只需运行:
python -m cProfile -o timeStats.profile timeFunctions.py
这是在使用cProfile模块来评测timeFunctions.py中的所有函数,并在timeStats.profile文件中收集统计信息。注意,我们不必向现有模块(timeFunctions.py)添加任何代码,这可以通过任何模块来完成。
一旦有了stats文件,就可以按如下方式运行pstats模块:
python -m pstats timeStats.profile
这将运行交互式统计浏览器,它为您提供了许多不错的功能。对于您的特定用例,您可以只检查函数的统计信息。在我们的示例中,检查两个函数的统计信息显示如下:
Welcome to the profile statistics browser.
timeStats.profile% stats hello
<timestamp> timeStats.profile
224 function calls in 6.014 seconds
Random listing order was used
List reduced from 6 to 1 due to restriction <'hello'>
ncalls tottime percall cumtime percall filename:lineno(function)
10 0.000 0.000 1.001 0.100 timeFunctions.py:3(hello)
timeStats.profile% stats thankyou
<timestamp> timeStats.profile
224 function calls in 6.014 seconds
Random listing order was used
List reduced from 6 to 1 due to restriction <'thankyou'>
ncalls tottime percall cumtime percall filename:lineno(function)
100 0.002 0.000 5.012 0.050 timeFunctions.py:7(thankyou)
这个假例子做不了什么,但给了你一个可以做什么的想法。这种方法最好的一点是,我不必编辑任何现有代码来获取这些数字,并且显然有助于分析。