Python精确统计函数执行时间的多种方法

 更新时间:2026年01月27日 09:31:36   作者:AI手记叨叨  
在软件开发中,我们常常需要了解代码的执行效率,本文将介绍 Python中统计 函数执行时间 的多种方法,及其适用场景和注意事项,需要的朋友可以参考下

一、为什么需要统计函数执行时间

  1. 识别性能瓶颈,优化关键代码路径
  2. 对比不同算法或实现的性能差异,量化优化效果
  3. 监控生产环境中关键功能的性能表现
  4. 建立性能基准,评估代码改进效果
  5. 诊断偶发的性能下降问题

二、Python中的时间统计方法

使用 time 模块

import time

start_time = time.time()  # 记录开始时间
your_function()          # 执行目标函数
end_time = time.time()   # 记录结束时间

execution_time = end_time - start_time
print(f"函数执行时间: {execution_time:.6f}秒")

特点

  • 简单直接
  • 精度约为毫秒级
  • 受系统时间调整影响

使用 time.perf_counter()

import time

start = time.perf_counter()  # 高精度计时器
your_function()
end = time.perf_counter()

print(f"函数执行时间: {end - start:.6f}秒")

特点

  • 精度可达纳秒级
  • 不受系统时间调整影响
  • 适合测量短时间间隔

注意
Windows 和 Linux 的底层计时机制不同,time.perf_counter()在不同操作系统上的精度可能略有差异。

使用 timeit 模块

import timeit

# 测量单次执行
time_taken = timeit.timeit('your_function()', 
                          setup='from __main__ import your_function',
                          number=1)
print(f"执行时间: {time_taken:.6f}秒")

# 测量多次执行求平均
repeat = 1000
total_time = timeit.timeit('your_function()', 
                         setup='from __main__ import your_function',
                         number=repeat)
print(f"平均执行时间: {total_time/repeat:.6f}秒")

特点

  • 自动禁用垃圾回收以获得更稳定结果
  • 适合测量小代码段的执行时间
  • 可以方便地重复多次测量

使用装饰器(推荐的解决方案)

import time
import functools

def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.perf_counter()
        result = func(*args, **kwargs)
        end_time = time.perf_counter()
        print(f"{func.__name__} 执行时间: {end_time - start_time:.6f}秒")
        return result
    return wrapper

@timer
def example_function(n):
    return sum(i*i for i in range(n))

example_function(1000000)

特点

  • 代码复用性高
  • 非侵入式测量
  • 可以轻松添加或移除计时功能

使用上下文管理器

from contextlib import contextmanager
import time

@contextmanager
def timer_context(name):
    start = time.perf_counter()
    yield
    end = time.perf_counter()
    print(f"{name} 执行时间: {end - start:.6f}秒")

with timer_context("复杂计算"):
    # 在这里执行需要计时的代码
    result = sum(i*i for i in range(1000000))

特点

  • 适合测量代码块的执行时间
  • 不需要封装函数
  • 可以嵌套使用

三、高级用法

对于更复杂的性能分析,可以使用 cProfile 模块:

import cProfile

def your_function():
    # 函数实现
    pass

# 运行性能分析
profiler = cProfile.Profile()
profiler.enable()
your_function()
profiler.disable()
profiler.print_stats(sort='time')

四、异步函数计时

异步代码(async/await)的计时需要特殊处理,可以使用 asyncio 模块提供的方法。

使用 asyncio 专用计时器

import asyncio

async def task():
    start = asyncio.get_event_loop().time()  # 事件循环内部时钟
    await asyncio.sleep(1)
    end = asyncio.get_event_loop().time()
    print(f"耗时: {end - start:.2f}秒")  # 准确记录协程生命周期

asyncio.run(task())

隔离CPU耗时(适用于混合计算/IO场景)

async def pure_cpu_work():
    start = time.perf_counter()  # 仅测量CPU计算部分
    result = sum(i*i for i in range(10**6))
    end = time.perf_counter()
    print(f"CPU计算耗时: {end - start:.2f}秒")
    return result

async def main():
    await pure_cpu_work()  # 只统计计算时间
    await asyncio.sleep(1)  # IO等待单独处理

asyncio.run(main())

使用 asyncio.run() 包装(Python 3.7+)

async def async_task():
    await asyncio.sleep(1)

start = time.perf_counter()
asyncio.run(async_task())  # 包含事件循环启动/关闭时间
end = time.perf_counter()
print(f"总耗时: {end - start:.2f}秒")

五、应用建议

精度选择

  • 对于长时间运行的任务(>1秒),使用 time.time() 足够
  • 对于短时间测量,使用 time.perf_counter()

多次测量

  • 对于快速函数,执行多次求平均值
  • 注意第一次执行可能因缓存等因素较慢

环境控制

  • 关闭其他占用CPU的程序
  • 在相同环境下进行比较测试

结果分析

  • 关注相对差异而非绝对数值
  • 考虑标准差而不仅是平均值

相对差异 vs 绝对数值

相对差异 = (新值 - 旧值)/旧值 × 100%
绝对数值 = 直接测量结果(如 0.25秒)

绝对差异0.05秒看似很小,但相对10%的提升可能是显著的
不同机器/环境下绝对数值会变化,但相对差异通常保持稳定
帮助判断优化有效性(如5%以下差异可能是测量误差)

平均值 vs 标准差

平均值:所有测量结果的平均数
标准差(σ):数据离散程度的度量

高标准差可能暗示:
存在资源竞争(如GC、线程切换)
特殊输入导致性能波动
测量环境不稳定

示例:

# 两组测量结果(单位:秒)
组A = [0.48, 0.49, 0.50, 0.51, 0.52]  # 平均值0.50,σ≈0.015
组B = [0.35, 0.45, 0.50, 0.55, 0.65]  # 平均值0.50,σ≈0.118
	
# 虽然平均值相同,但:
# - 组A性能稳定
# - 组B存在偶发的严重性能下降

在需要稳定性的场景(如实时系统),低标准差比低平均值更重要。

六、常见误区

  1. 只测量一次:单次测量可能受系统波动影响
  2. 忽略预热效应:第一次执行通常较慢
  3. 测量包含打印时间:I/O操作会显著影响结果
  4. 在开发环境评估生产性能:环境差异可能导致结果不准确

七、总结

Python 提供了多种统计函数执行时间的方法,从简单的 time.time() 到专业的 cProfile 工具。选择合适的方法取决于具体需求:

  • 快速检查:使用 time.time() 或装饰器
  • 精确测量:使用 time.perf_counter()
  • 重复测试:使用 timeit
  • 全面分析:使用 cProfile

通过合理使用这些工具,可以有效地识别和解决性能问题,提升代码效率。

以上就是Python统计函数执行时间的多种方法的详细内容,更多关于Python统计函数执行时间的资料请关注脚本之家其它相关文章!

相关文章

  • matplotlib 画双轴子图无法显示x轴的解决方法

    matplotlib 画双轴子图无法显示x轴的解决方法

    这篇文章主要介绍了matplotlib 画双轴子图无法显示x轴的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • python 移动图片到另外一个文件夹的实例

    python 移动图片到另外一个文件夹的实例

    今天小编就为大家分享一篇python 移动图片到另外一个文件夹的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • Python之列表的插入&替换修改方法

    Python之列表的插入&替换修改方法

    今天小编就为大家分享一篇Python之列表的插入&替换修改方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-06-06
  • Python中性能的深度解析和提升方法

    Python中性能的深度解析和提升方法

    为一门广受欢迎的编程语言,Python 以其简洁的语法、强大的库生态和极高的开发效率赢得了无数开发者的青睐,下面将带你深入探讨 Python 的性能奥秘,帮助你理解其背后的原理,学会如何评估性能,并在必要时进行优化
    2025-11-11
  • Pytorch中torch.stack()函数的深入解析

    Pytorch中torch.stack()函数的深入解析

    在pytorch中常见的拼接函数主要是两个,分别是:stack()和cat(),下面这篇文章主要给大家介绍了关于Pytorch中torch.stack()函数的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • python3 使用ssh隧道连接mysql的操作

    python3 使用ssh隧道连接mysql的操作

    这篇文章主要介绍了python3 使用ssh隧道连接mysql的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 分析经典Python开发工程师面试题

    分析经典Python开发工程师面试题

    在本篇内容中小编给大家分享了一篇关于Python开发工程师面试题的相关总结内容,需要的朋友们学习下。
    2019-04-04
  • Python创建日历实例

    Python创建日历实例

    这篇文章主要介绍了Python创建日历实例,不使用Python提供的calendar实现,需要的朋友可以参考下
    2014-08-08
  • python超时重新请求解决方案

    python超时重新请求解决方案

    这篇文章主要介绍了python超时重新请求解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • Python绘制股票移动均线的实例

    Python绘制股票移动均线的实例

    今天小编就为大家分享一篇Python绘制股票移动均线的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08

最新评论