14.13 给你的程序做性能测试

问题

你想测试你的程序运行所花费的时间并做性能测试。

解决方案

如果你只是简单的想测试下你的程序整体花费的时间, 通常使用 Unix 时间函数就行了,比如:

bash % time python3 someprogram.py

如果你还需要一个程序各个细节的详细报告,可以使用 cProfile 模块:

bash % python3 -m cProfile someprogram.py

不过通常情况是介于这两个极端之间。比如你已经知道代码运行时在少数几个函数中花费了绝大部分时间。 对于这些函数的性能测试,可以使用一个简单的装饰器:

# timethis.py

import time
from functools import wraps

def timethis(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        r = func(*args, **kwargs)
        end = time.perf_counter()
        print('{}.{} : {}'.format(func.__module__, func.__name__, end - start))
        return r
    return wrapper

要使用这个装饰器,只需要将其放置在你要进行性能测试的函数定义前即可,比如:

要测试某个代码块运行时间,你可以定义一个上下文管理器,例如:

下面是使用这个上下文管理器的例子:

对于测试很小的代码片段运行性能,使用 timeit 模块会很方便,例如:

timeit 会执行第一个参数中语句 100 万次并计算运行时间。 第二个参数是运行测试之前配置环境。如果你想改变循环执行次数, 可以像下面这样设置 number 参数的值:

讨论

当执行性能测试的时候,需要注意的是你获取的结果都是近似值。 time.perf_counter() 函数会在给定平台上获取最高精度的计时值。 不过,它仍然还是基于时钟时间,很多因素会影响到它的精确度,比如机器负载。 如果你对于执行时间更感兴趣,使用 time.process_time() 来代替它。例如:

最后,如果你想进行更深入的性能分析,那么你需要详细阅读 timetimeit 和其他相关模块的文档。 这样你可以理解和平台相关的差异以及一些其他陷阱。

Last updated

Was this helpful?