M-AzurLaneAutoScript/module/webui/performance_timer.py

92 lines
3.3 KiB
Python
Raw Normal View History

import time
import functools
from typing import Optional, Callable
from contextlib import contextmanager
from module.logger import logger
class PerformanceTimer:
"""性能计时器,用于测量函数执行时间"""
@staticmethod
def timer(name: Optional[str] = None, log_level: str = "info", threshold_ms: float = 0):
"""
函数计时装饰器
Args:
name: 自定义名称默认使用函数名
log_level: 日志级别 (debug, info, warning, error)
threshold_ms: 只记录超过阈值的执行时间(毫秒)0表示记录所有
"""
def decorator(func: Callable):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start_time = time.perf_counter()
try:
result = func(*args, **kwargs)
return result
finally:
end_time = time.perf_counter()
duration_ms = (end_time - start_time) * 1000
if duration_ms >= threshold_ms:
func_name = name or f"{func.__module__}.{func.__qualname__}"
log_msg = f"⏱️ [{func_name}] 执行耗时: {duration_ms:.2f}ms"
# 根据耗时选择日志级别
if duration_ms > 1000: # 超过1秒
logger.warning(f"🐌 {log_msg} (性能警告)")
elif duration_ms > 100: # 超过100ms
logger.info(f"⚠️ {log_msg}")
else:
getattr(logger, log_level)(log_msg)
return wrapper
return decorator
@staticmethod
@contextmanager
def measure(name: str, log_level: str = "info", threshold_ms: float = 0):
"""
上下文管理器计时
使用示例:
with PerformanceTimer.measure("数据库查询"):
# 执行代码
pass
"""
start_time = time.perf_counter()
try:
yield
finally:
end_time = time.perf_counter()
duration_ms = (end_time - start_time) * 1000
if duration_ms >= threshold_ms:
log_msg = f"⏱️ [{name}] 执行耗时: {duration_ms:.2f}ms"
if duration_ms > 1000: # 超过1秒
logger.warning(f"🐌 {log_msg} (性能警告)")
elif duration_ms > 100: # 超过100ms
logger.info(f"⚠️ {log_msg}")
else:
getattr(logger, log_level)(log_msg)
# 便捷的装饰器别名
timer = PerformanceTimer.timer
measure = PerformanceTimer.measure
# 预定义的常用装饰器
def critical_timer(name: Optional[str] = None):
"""关键路径计时器 - 记录所有执行时间"""
return timer(name=name, log_level="info", threshold_ms=0)
def slow_timer(name: Optional[str] = None):
"""慢操作计时器 - 只记录超过50ms的操作"""
return timer(name=name, log_level="info", threshold_ms=100)
def debug_timer(name: Optional[str] = None):
"""调试计时器 - 只记录超过10ms的操作"""
return timer(name=name, log_level="debug", threshold_ms=10)