5种方法对python程序代码做性能分析和计时统计

本文介绍了多种Python代码运行时间的统计方法,包括使用time.time()、time.clock()、time命令、cProfile模块、timeit模块及装饰器等,并对逐行分析工具line_profiler进行了介绍。

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

python代码运行时间统计

以下方法分别针对 代码块、代码程序文件、 函数 进行性能计时统计

一、time.time() 或者 datetime.datetime.now()

返回当前时间的时间戳 如 1524302633.980187
两次时间相减,代码运行所需的 挂钟时间,也就是命令开始执行到结束的时间。

import time
start = time.time()
print("Hello World")
time.sleep(2)
end = time.time()
print(end - start)

输出

Hello World
2.0038700103759766

二、time.clock()

clock() 函数以浮点数计算的秒数返回当前的CPU时间。用来衡量不同程序的耗时,比time.time()更有用。
在win系统下,这个函数返回的是真实时间(wall time),而在Unix/Linux下返回的是CPU时间。

#文件 test.py
import time
start = time.clock()
print("Hello World")
time.sleep(2)
end = time.clock()
print(end - start)

linux 下输出

Hello World
 0.00020299999999999485

time.clock(),python 3.3版本以后这个函数被废弃了,但是这个函数仍然可以使用。

三、time

在linux下对整个程序做计时统计
time python test.py
如果time 命令报错,可以使用/usr/bin/time 而不是time

/usr/bin/time -p python test.py

输出内容
real 0m2.057s
user 0m0.033s
sys 0m0.011s

real 记录了整体的耗时
user 记录了 CPU花在任务上的时间,但不包括内核函数花费的时间
sys 记录了内核函数花费的时间
对user和sys 相加就得到了CPU总共花费的时间。而这个时间和real的差则有可能是花费在等待IO上。

可以打开–verbose开关来获得更多输出信息
/usr/bin/timee --verbose python test.py

四、cProfile

cProfile:基于lsprof的用C语言实现的扩展应用,运行开销比较合理,适合分析运行时间较长的程序,推荐使用这个模块;
python -m cProfile test.py
python -m cProfile -o profile.stats test.py
生成一个统计文件然后通过python进行分析
import pstats
p = pstats.Stats(“profile.stats”)
p.print_stats()

Hello World
0.00010600000000000193
         8 function calls in 2.005 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    2.005    2.005 test.py:3(<module>)
        1    0.000    0.000    2.005    2.005 {built-in method builtins.exec}
        2    0.000    0.000    0.000    0.000 {built-in method builtins.print}
        2    0.000    0.000    0.000    0.000 {built-in method time.clock}
        1    2.005    2.005    2.005    2.005 {built-in method time.sleep}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

ncalls:表示函数调用的次数;
tottime:表示指定函数的总的运行时间,除掉函数中调用子函数的运行时间;
percall:(第一个percall)等于 tottime/ncalls;
cumtime:表示该函数及其所有子函数的调用运行的时间,即函数开始调用到返回的时间;
percall:(第二个percall)即函数运行一次的平均时间,等于 cumtime/ncalls;
filename:lineno(function):每个函数调用的具体信息;

用runsnakerun 对cProfile的输出进行可视化
pip install runsnake 来安装,需要wxPython,在virtualenv下安装会比较麻烦。没试过,记录下。
来自书籍《python高性能编程》

五、 timeit

from timeit import timeit

timeit('math.sqrt(2)', 'import math', number=100000)

六、装饰器–对函数进行计时统计

定义装饰器timethis
将装饰器放在函数定义之前,就能得到对应函数的计时信息

from functools import wraps
import time

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

@timethis
def ts():
    time.sleep(2)
    print("Hello World")

ts()

输出
Hello World
main.ts : 2.0007375059940387

七、用line_profiler进行逐行分析

用cProfile找到需要分析的函数,然后用line_profiler对函数进行分析。line_profiler可以帮你一行一行分析函数性能
pip install line_profiler

运行kernprof 逐行分析被修饰函数的CPU开销
kernprof.py -l -v test.py
-v 显示输出
-l 代表逐行分析而不是逐函数分析

Total Time:测试代码的总运行时间
Hits:表示每行代码运行的次数
Time:每行代码运行的总时间
Per Hits:每行代码运行一次的时间
% Time:每行代码运行时间的百分比

备注

使用time.perf_counter() 能够提供给定平台上精度最高的计时器,但是,它计算的仍然是时钟时间,很多因素会影响到它的精确度,比如机器负载。
如果你对于执行时间更感兴趣,使用time.process_time() 来代替它。

<think>好的,我现在要帮用户解决如何用Python统计代码运行时间的问题。用户提到了使用time或datetime库,所以我得先回忆这两个库的具体用法。首先,time模块是常用的计时工具,里面有time()perf_counter()函数,可能还有process_time()。需要区分这些函数的不同之处,比如time()返回的是当前时间戳,而perf_counter()适合测量时间间隔,包括睡眠时间,而process_time()只计算CPU时间,不包括睡眠。 然后,用户可能还需要更简单的上下文管理器或者装饰器来测量代码块的执行时间,这样更方便。比如用contextlib中的contextmanager来创建一个计时器,或者写一个装饰器来测量函数执行时间。这样用户可以在需要的时候快速应用,而不必重复写计时代码。 接着,datetime模块虽然主要用于处理日期时间,但也可以用来计算时间差,不过可能不如time模块直接。需要比较两者的优劣,指出time更适合精确的时间测量。 还要考虑用户的实际使用场景,他们可能是在调试或优化代码性能,所以需要给出不同精度的选择,比如高精度需求用perf_counter,普通需求用time。同时,提醒他们多次运行取平均值,以减少其他进程的干扰。 另外,用户提供的引用内容中提到了time模块的gmtime、localtime等函数,但这些可能更多用于获取时间结构,而不是测量执行时间。需要明确说明哪些函数适合计时,避免混淆。 最后,生成相关问题的时候,要考虑用户可能的后续需求,比如如何格式化输出时间、处理多线程程序的计时、或者比较不同计时方法的优劣。这些问题可以帮助用户更深入地了解性能测试的各个方面。</think>Python中测量代码执行时间主要有三种常用方法,每种方法适用于不同的场景: ### 一、使用time模块基础方法 ```python import time start = time.time() # 获取当前时间戳 # 被测代码 result = sum(range(10**6)) end = time.time() print(f"执行耗时:{end - start:.4f}秒") ``` 这是最基本的计时方法,精度约为1毫秒[^1]。适合粗略测量较长耗时任务。 ### 二、高精度计时(推荐) ```python start = time.perf_counter() # 包含睡眠时间的精确计时 # 被测代码 time.sleep(1.5) end = time.perf_counter() print(f"高精度耗时:{end - start:.6f}秒") ``` `perf_counter()`提供纳秒级精度,适合需要精确测量的场景。 ### 三、CPU时间测量 ```python start = time.process_time() # 仅计算CPU时间 # 被测代码 sum([x**2 for x in range(10**6)]) end = time.process_time() print(f"CPU耗时:{end - start:.2f}秒") ``` process_time()忽略系统睡眠时间,适用于计算纯CPU运算时间。 ### 四、进阶用法(上下文管理器) ```python from contextlib import contextmanager import time @contextmanager def timer(): try: start = time.perf_counter() yield finally: end = time.perf_counter() print(f"耗时:{end - start:.4f}秒") # 使用示例 with timer(): data = [x**0.5 for x in range(10**6)] ``` ### 五、装饰器模式 ```python def timeit(func): def wrapper(*args, **kwargs): start = time.perf_counter() result = func(*args, **kwargs) print(f"{func.__name__} 耗时:{time.perf_counter() - start:.4f}s") return result return wrapper @timeit def process_data(n): return sum(x**2 for x in range(n)) process_data(10**6) ``` **注意事项:** 1. 多次运行取平均值(推荐至少3次) 2. 避免在测量期间运行其他程序 3. 对短时操作(<0.1秒)应增加循环次数 4. 使用`timeit`模块内置工具更专业(适合代码片段测试) ```python import timeit t = timeit.Timer('sum(range(1000))') print(t.timeit(number=10000)) # 执行10000次的平均耗时 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值