文章目录
- import time start_time = time.time() # 记录开始时间 your_function() # 执行目标函数 end_time = time.time() # 记录结束时间 execution_time = end_time – start_time print(f”函数执行时间: {execution_time:.6f}秒”) 特点: 简单直接 精度约为毫秒级 受系统时间调整影响
- import time start = time.perf_counter() # 高精度计时器 your_function() end = time.perf_counter() print(f”函数执行时间: {end – start:.6f}秒”) 特点: 精度可达纳秒级 不受系统时间调整影响 适合测量短时间间隔 注意Windows 和 Linux 的底层计时机制不同,time.perf_counter()在不同操作系统上的精度可能略有差异。
- 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)) 特点: 适合测量代码块的执行时间 不需要封装函数 可以嵌套使用
- 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())
- 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())
- 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的程序 在相同环境下进行比较测试
- 关注相对差异而非绝对数值
考虑标准差而不仅是平均值
- 相对差异 = (新值 – 旧值)/旧值 × 100%绝对数值 = 直接测量结果(如 0.25秒) 绝对差异0.05秒看似很小,但相对10%的提升可能是显著的不同机器/环境下绝对数值会变化,但相对差异通常保持稳定帮助判断优化有效性(如5%以下差异可能是测量误差)
- 平均值:所有测量结果的平均数标准差(σ):数据离散程度的度量 高标准差可能暗示:存在资源竞争(如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存在偶发的严重性能下降 在需要稳定性的场景(如实时系统),低标准差比低平均值更重要。
目录
- 一、为什么需要统计函数执行时间
- 二、Python中的时间统计方法
- 使用 time 模块
- 使用 time.perf_counter()
- 使用 timeit 模块
- 使用装饰器(推荐的解决方案)
- 使用上下文管理器
- 三、高级用法
- 四、异步函数计时
- 使用 asyncio 专用计时器
- 隔离CPU耗时(适用于混合计算/IO场景)
- 使用 asyncio.run() 包装(Python 3.7+)
- 五、应用建议
- 精度选择
- 多次测量
- 环境控制
- 结果分析
- 相对差异 vs 绝对数值
- 平均值 vs 标准差
- 六、常见误区
- 七、总结
- 识别性能瓶颈,优化关键代码路径
- 对比不同算法或实现的性能差异,量化优化效果
- 监控生产环境中关键功能的性能表现
- 建立性能基准,评估代码改进效果
- 诊断偶发的性能下降问题
import time
start_time = time.time() # 记录开始时间
your_function() # 执行目标函数
end_time = time.time() # 记录结束时间
execution_time = end_time - start_time
print(f"函数执行时间: {execution_time:.6f}秒")
特点:
- 简单直接
- 精度约为毫秒级
- 受系统时间调整影响
import time
start = time.perf_counter() # 高精度计时器
your_function()
end = time.perf_counter()
print(f"函数执行时间: {end - start:.6f}秒")
特点:
- 精度可达纳秒级
- 不受系统时间调整影响
- 适合测量短时间间隔
注意
Windows 和 Linux 的底层计时机制不同,time.perf_counter()在不同操作系统上的精度可能略有差异。
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 模块提供的方法。
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())
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())
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()
time.time() 足够time.perf_counter()
- 对于快速函数,执行多次求平均值
- 注意第一次执行可能因缓存等因素较慢
- 关闭其他占用CPU的程序
- 在相同环境下进行比较测试
- 关注相对差异而非绝对数值
- 考虑标准差而不仅是平均值
相对差异 = (新值 – 旧值)/旧值 × 100%
绝对数值 = 直接测量结果(如 0.25秒)
绝对差异0.05秒看似很小,但相对10%的提升可能是显著的
不同机器/环境下绝对数值会变化,但相对差异通常保持稳定
帮助判断优化有效性(如5%以下差异可能是测量误差)
平均值:所有测量结果的平均数
标准差(σ):数据离散程度的度量
高标准差可能暗示:
存在资源竞争(如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存在偶发的严重性能下降
在需要稳定性的场景(如实时系统),低标准差比低平均值更重要。
- 只测量一次:单次测量可能受系统波动影响
- 忽略预热效应:第一次执行通常较慢
- 测量包含打印时间:I/O操作会显著影响结果
- 在开发环境评估生产性能:环境差异可能导致结果不准确
Python 提供了多种统计函数执行时间的方法,从简单的 time.time() 到专业的 cProfile 工具。选择合适的方法取决于具体需求:
- 快速检查:使用
time.time()或装饰器 - 精确测量:使用
time.perf_counter() - 重复测试:使用
timeit - 全面分析:使用
cProfile
通过合理使用这些工具,可以有效地识别和解决性能问题,提升代码效率。
以上就是Python统计函数执行时间的多种方法的详细内容,更多关于Python统计函数执行时间的资料请关注风君子博客其它相关文章!
您可能感兴趣的文章:
- Python中计算函数执行时间的五种方法
- 计算python脚本执行时间的多种方法
- Python实现计算函数或程序执行时间
- Python实现监控内存使用情况和代码执行时间
- Python执行时间计算方法以及优化总结