Python 监控代码时间和空间消耗
1、测试代码运行时间
测试一段代码或函数运行的时间,可能通过 timeit
模块实现。
1.1使用 Timer().timeit() 进行测试
Timer(stmt="pass", setup="pass", timer=default_timer, globals=None)
- stamt:要执行的代码/函数
- setup:执行代码的准备工作,不计入时间,一般是 import 之类的
- timer:在 win32 下是time.clock(),linux下是 time.time(),使用系统默认即可
timeit(number=default_number)
- number:运行 stamt 的次数
例1:运行 test1() 函数 1000 次花费的时间
def test1():
l = []
for i in range(1000):
l = l + [i]
from timeit import Timer
t1 = Timer("test1()", "from __main__ import test1")
milliseconds = t1.timeit(number=1000)
print(f"It takes {milliseconds} milliseconds to run the test1() function 1000 times")
1.2 使用 timeit.timeit() 进行测试
timeit(stmt="pass", setup="pass", timer=default_timer, number=default_number, globals=None)
- stamt:要执行的代码/函数
- setup:执行代码的准备工作,不计入时间,一般是 import 之类的
- timer:在 win32 下是time.clock(),linux下是 time.time(),使用系统默认即可
- number:运行 stamt 的次数
例2:运行 test1() 函数 1000 次花费的时间
def test1():
l = []
for i in range(1000):
l = l + [i]
import timeit
milliseconds = timeit.timeit(stmt="test1()",setup="from __main__ import test1", number=1000)
print(f"It takes {milliseconds} milliseconds to run the test1() function 1000 times")
说明:
实际上timeit.timeit()
也是通过Timer()
实现的。
你可能非常熟悉 from ,import 语句,但这通常用在 python 程序文件的开头。在这种情况下,from main import test1 从 main 命名空间导入到 timeit 设置的命名空间中。timeit 这么做是因为它想在一个干净的环境中做测试,而不会因为可能有你创建的任何杂变量,以一种不可预见的方式干扰你函数的性能。
2、时间消耗分析
获取 Python 代码时间消耗,可以利用 line_profiler
模块计算出执行每行代码占用 CPU 时间。
2.1 安装
首先安装 line_profiler。
2.2 示例
下面是 Demo 示例:
from line_profiler import LineProfiler
def test1():
count = 0
for i in range(10000):
count += 1
def test2():
count = 0
while (count < 10000):
count += 1
if __name__ == "__main__":
lp = LineProfiler(test1, test2)
lp.run('test1()')
lp.run('test2()')
lp.print_stats()
执行结果:
2.3 结果信息
- Line #: 文件中的行号。
- Hits: 该行被执行的次数。
- Time: 在定时器在单位中执行该行所花费的总时间。在表前面的头信息中,您将看"Timer unit:"这一行,它给出了秒的转换因子。在不同的系统上可能不同。
- Per Hit: 在定时器单位执行中,执行一次行的平均时间。
- % Time: 花费在该行上的时间相对于花费在函数上的总时间的百分比。
- Line Contents: 实际的源代码。请注意,这总是在查看格式化结果时从磁盘读取,而不是在执行代码时。如果您同时编辑了文件,那么行将不匹配,格式化程序甚至可能无法找到要显示的函数。
2.4 结果分析
以 test1() 函数示例结果分析:
在定时器中,单位时间为 3.52594e-07 s
,Time 为执行了多少次单位时间。
执行该程序所花费的总系统时间是:(4 + 9757 + 10942) * 3.52594e-07 s = 0.00729975 s
3、空间消耗
3.1 安装
首先安装 memory_profiler。
3.2 示例
使用装饰器实现。
下面是 Demo 示例1:
from memory_profiler import profile
@profile
def my_func():
a = [1] * (10 ** 6)
b = [2] * (2 * 10 ** 7)
del b
return a
if __name__ == '__main__':
my_func()
执行结果:
- Line #:分析的代码的行号。
- Mem usage:表示执行该行后 Python 解释器的内存使用情况。
- Increment:表示当前行与最后一行的内存差异。
- Line Contents:打印已分析的代码。
下面是 Demo 示例2,给装饰器指定一个精度参数:
from memory_profiler import profile
@profile(precision=4)
def my_func():
a = [1] * (10 ** 6)
b = [2] * (2 * 10 ** 7)
del b
return a
if __name__ == '__main__':
my_func()
执行结果: