Python程序性能测试小方法

本文介绍了如何使用PyCharmIDE进行代码性能测试,以及通过Unix系统命令、Python内置time模块和timeit模块来评估代码效率,包括time.time(),time.perf_counter(),time.process_time()和timeit.timeit/repeat的功能和使用示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里记录几种测试Python程序性能的方法。

1、集成开发工具IDE,例:PyCharm。

现在的IDE基本上能满足开发人员的各种基本需求,当然了,性能测试也不例外,PyCharm作为Pythoner的主流IDE,这样的需求也是不在话下,编写好你的程序之后,至于要右击你的代码页面,找到 profile xxx 选项,其中 xxx 为你的代码文件名,点击后,它会弹出一个性能测试页面,里面包含了你代码中各个耗时操作的性能分析,包括一些堆栈调用。

2、使用Unix 系统自带的时间工具time。

同样的,假设现在我们有这样的一个代码文件 code.py,代码如下:

a = [i * 2 for i in range(10000000)]

我们在Unix系统中使用如下命令行运行上面的代码文件:

time python code.py

运行结果如下:

real    0m0.132s
user    0m0.000s
sys     0m0.031s

这三个结果分别表示:

  • real 记录了程序运行整体的耗时;

  • user 记录了 CPU 花在任务上的时间,但不包括内核函数耗费的时间;

  • sys 记录了内核函数耗费的时间。

3、使用Python内置的模块,如:timetimeit

相对来说 time 模块大家都比较熟悉,其中有几个方法可供大家调用:

  • time.time()

    import time 
    
    s = time.time()
    a = [i ** 2 for i in range(1000000)]
    e = time.time()
    print(f"s: {s}")
    print(f"e: {e}")
    print(f"Time cost {e - s} s.")
    

    结果如下:

    s: 1671764979.9903982
    e: 1671764980.7124395
    Time cost 0.7220413684844971 s.
    
  • time.perf_counter()

    import time 
    
    s = time.perf_counter()
    a = [i ** 2 for i in range(1000000)]
    e = time.perf_counter()
    print(f"s: {s}")
    print(f"e: {e}")
    print(f"Time cost {e - s} s.")
    

    结果如下:

    s: 2.054608198544187e-06
    e: 0.7287198065052183
    Time cost 0.7287177518970197 s.
    
  • time.process_time()

    import time 
    
    s = time.process_time()
    a = [i ** 2 for i in range(1000000)]
    e = time.process_time()
    print(f"s: {s}")
    print(f"e: {e}")
    print(f"Time cost {e - s} s.")
    

    结果如下:

    s: 0.09360059999999999
    e: 0.7332046999999999
    Time cost 0.6396040999999999 s.
    

    我们在代码中加上 time.sleep

    import time 
    
    s = time.process_time()
    a = [i ** 2 for i in range(1000000)]
    time.sleep(3)
    e = time.process_time()
    print(f"s: {s}")
    print(f"e: {e}")
    print(f"Time cost {e - s} s.")
    

    结果如下:

    s: 0.0780005
    e: 0.7644048999999999
    Time cost 0.6864043999999999 s.
    

好了,接下来就是对比三者之间的区别,通过上面的代码相信大家应该轻松就能应用起来:

  • time.time():返回当前时间的时间戳(1970纪元后经过的浮点秒数),计算程序性能时,包含系统休眠时间。
  • time.perf_counter():从当前计算机系统中选取一个时间点,在测试耗时较短的代码性能上,具有最高可用分辨率。计算程序性能时,包含系统休眠时间。只有在连续调用结果之间的差异才有效。
  • time.process_time():返回当前进程的系统和用户CPU时间总和的值(以小数秒为单位)。它不包括睡眠期间经过的时间。同样的,只有在连续调用结果之间的差异才有效。

接下来是 timeit 模块:

比较重要的两个方法的源码如下:

def timeit(stmt="pass", setup="pass", timer=default_timer,
           number=default_number, globals=None):
    """Convenience function to create Timer object and call timeit method."""
    return Timer(stmt, setup, timer, globals).timeit(number)

def repeat(stmt="pass", setup="pass", timer=default_timer,
           repeat=default_repeat, number=default_number, globals=None):
    """Convenience function to create Timer object and call repeat method."""
    return Timer(stmt, setup, timer, globals).repeat(repeat, number)

参数释义:

  • stmt:用于传入要测试时间的代码,可以直接接受字符串的表达式,也可以接受单个变量,也可以接受函数。传入函数时要把函数申明在当前文件中,然后在 stmt = func() 执行函数,然后使用setup = from __main__ import func
  • setup:传入stmt的运行环境,比如stmt中使用到的参数、变量,要导入的模块等。可以写一行语句,也可以写多行语句,写多行语句时要用分号;隔开语句。
  • number:要测试的代码的运行次数,默认100000次,对于耗时的代码,运行太多次会比较慢,此时建议自己修改一下运行次数
  • repeat:指测试要重复几次,每次的结果构成列表返回,默认3次。
  1. 直接构建测试语句并运行:
import timeit

stat1 = timeit.timeit(stmt="[i ** 2 for i in range(N)]", setup="N = 1000000", number=10)
print(f"Test sentence 1: {stat1}")

stat2 = timeit.repeat(stmt="[i ** 2 for i in range(N)]", setup="N = 1000000", number=10, repeat=2)
print(f"Test sentence 2: {stat2}")

# 复合语句作为代码块
stat3 = timeit.timeit(stmt="[i + bonus for i in range(N)]", setup="N = 1000000;bonus=100", number=10)
print(f"Test sentence 3: {stat3}")

stat4 = timeit.repeat(stmt="[i + bonus for i in range(N)]", setup="N = 1000000;bonus=100", number=10, repeat=2)
print(f"Test sentence 4: {stat4}")


# 以函数调用的形式完成统计
def seeker():
    N = 1000000
    bonus = 100
    return [i + bonus for i in range(N)]


stat5 = timeit.timeit(stmt="seeker()", setup="from __main__ import seeker", number=10)
print(f"Test sentence 5: {stat5}")

stat6 = timeit.repeat(stmt="seeker()", setup="from __main__ import seeker", number=10, repeat=3)
print(f"Test sentence 6: {stat6}")

​ 运行结果如下:

Test sentence 1: 5.334041077370792
Test sentence 2: [5.435822258310274, 5.48210682812052]
Test sentence 3: 1.6497468311777759
Test sentence 4: [1.5984531265794786, 1.5951452073798258]
Test sentence 5: 1.6178880764511483
Test sentence 6: [1.599862998725321, 1.590234282863662, 1.5924134003190389]
  1. 先构造 pipline 实例,这里有特定的方法 Timer,再传入指定参数并运行:
import timeit

timer1 = timeit.Timer(stmt="[i + bonus for i in range(N)]", setup="N = 1000000;bonus = 100")
stat1 = timer1.timeit(number=10)
print(f"Test sentence 1: {stat1}")

stat2 = timer1.repeat(number=10, repeat=2)
print(f"Test sentence 2: {stat2}")

# 使用函数的方式进行调用
def seeker():
    N = 1000000
    bonus = 100
    return [i + bonus for i in range(N)]


timer2 = timeit.Timer(stmt="seeker()", setup="from __main__ import seeker")
stat3 = timer2.timeit(number=10)
print(f"Test sentence 3: {stat3}")

stat4 = timer2.repeat(number=10, repeat=2)
print(f"Test sentence 4: {stat4}")

运行结果如下:

Test sentence 1: 1.7151524067269517
Test sentence 2: [1.6136428449913172, 1.5879380527409706]
Test sentence 3: 1.59479880043755
Test sentence 4: [1.5951669862267277, 1.5980076875220348]

以上,大家可以根据自己的喜好去选择使用对应的测试方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值