本文目录导读:

- 方法1:使用时间戳(最简单)
- 方法2:使用装饰器统计单个协程耗时
- 方法3:使用上下文管理器(推荐)
- 方法4:统计所有协程的详细耗时
- 方法5:使用asyncio的内置功能
- 方法6:高级统计(包含异常处理)
- 总结建议
在Python中统计协程任务执行耗时,有几种常见方法:
方法1:使用时间戳(最简单)
import asyncio
import time
async def my_task(task_id):
print(f"任务 {task_id} 开始")
await asyncio.sleep(2) # 模拟耗时操作
print(f"任务 {task_id} 结束")
async def main():
start_time = time.time()
# 执行多个协程
tasks = [my_task(i) for i in range(3)]
await asyncio.gather(*tasks)
total_time = time.time() - start_time
print(f"所有任务总耗时: {total_time:.2f} 秒")
asyncio.run(main())
方法2:使用装饰器统计单个协程耗时
import asyncio
import time
from functools import wraps
def async_timer(func):
@wraps(func)
async def wrapper(*args, **kwargs):
start_time = time.time()
result = await func(*args, **kwargs)
elapsed = time.time() - start_time
print(f"{func.__name__} 执行耗时: {elapsed:.4f} 秒")
return result
return wrapper
@async_timer
async def my_task(task_id):
await asyncio.sleep(task_id)
return f"任务 {task_id} 完成"
async def main():
tasks = [my_task(i) for i in range(1, 4)]
results = await asyncio.gather(*tasks)
print("结果:", results)
asyncio.run(main())
方法3:使用上下文管理器(推荐)
import asyncio
import time
from contextlib import asynccontextmanager
@asynccontextmanager
async def timer_context(name="任务"):
start_time = time.time()
yield
elapsed = time.time() - start_time
print(f"{name} 耗时: {elapsed:.2f} 秒")
async def my_task(task_id):
await asyncio.sleep(task_id)
async def main():
async with timer_context("总任务"):
async with timer_context(f"子任务"):
await my_task(2)
await my_task(1)
asyncio.run(main())
方法4:统计所有协程的详细耗时
import asyncio
import time
class TaskTimer:
def __init__(self):
self.tasks = {}
def start_task(self, task_id):
self.tasks[task_id] = time.time()
def end_task(self, task_id):
if task_id in self.tasks:
elapsed = time.time() - self.tasks[task_id]
del self.tasks[task_id]
return elapsed
return None
def get_stats(self):
return self.tasks
async def my_task(task_id, timer):
timer.start_task(task_id)
print(f"任务 {task_id} 开始")
await asyncio.sleep(task_id)
elapsed = timer.end_task(task_id)
print(f"任务 {task_id} 耗时: {elapsed:.2f} 秒")
return task_id
async def main():
timer = TaskTimer()
tasks = [my_task(i, timer) for i in range(1, 4)]
results = await asyncio.gather(*tasks)
print("所有任务完成:", results)
asyncio.run(main())
方法5:使用asyncio的内置功能
import asyncio
import time
async def my_task(task_id):
await asyncio.sleep(task_id)
return f"任务 {task_id}"
async def main():
# 创建任务,获取完成时间
tasks = [asyncio.ensure_future(my_task(i)) for i in range(1, 4)]
start = time.time()
done, pending = await asyncio.wait(tasks)
total = time.time() - start
print(f"总耗时: {total:.2f} 秒")
print(f"完成的任务: {len(done)}")
print(f"未完成的任务: {len(pending)}")
# 获取每个任务的结果
for task in done:
print(f"结果: {task.result()}")
asyncio.run(main())
方法6:高级统计(包含异常处理)
import asyncio
import time
from typing import Dict, List, Tuple
class AsyncTaskProfiler:
def __init__(self):
self.timings: Dict[str, float] = {}
async def profile(self, coro, name=None):
"""分析单个协程"""
name = name or coro.__name__
start = time.time()
try:
result = await coro
elapsed = time.time() - start
self.timings[name] = elapsed
return result
except Exception as e:
elapsed = time.time() - start
self.timings[name] = elapsed
raise e
async def profile_all(self, coros: List) -> Tuple:
"""分析多个协程"""
tasks = []
for coro in coros:
task = asyncio.create_task(self.profile(coro))
tasks.append(task)
results = await asyncio.gather(*tasks, return_exceptions=True)
return results
def get_report(self) -> str:
"""生成统计报告"""
if not self.timings:
return "没有统计数据"
total = sum(self.timings.values())
report = ["任务执行报告:", "-" * 30]
for name, timing in self.timings.items():
percentage = (timing / total) * 100 if total > 0 else 0
report.append(f"{name}: {timing:.3f}秒 ({percentage:.1f}%)")
report.append("-" * 30)
report.append(f"总计: {total:.3f}秒")
return "\n".join(report)
async def main():
profiler = AsyncTaskProfiler()
# 定义几个异步任务
async def task_a():
await asyncio.sleep(1)
return "A完成"
async def task_b():
await asyncio.sleep(2)
return "B完成"
async def task_c():
await asyncio.sleep(0.5)
return "C完成"
# 分析所有任务
coros = [task_a(), task_b(), task_c()]
results = await profiler.profile_all(coros)
# 输出报告
print(profiler.get_report())
print("结果:", results)
asyncio.run(main())
总结建议
- 简单场景:使用方法1(时间戳)最直接
- 需要复用:使用方法2(装饰器)或方法3(上下文管理器)
- 需要详细统计:使用方法4(自定义类)或方法6(完整分析器)
- 生产环境:考虑使用专门的性能分析库如
asyncio-profiler或yappi
推荐使用方法3(上下文管理器),因为它:
- 代码干净,易于阅读
- 可以精确控制计时范围
- 支持嵌套计时
- 易于扩展和维护
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播