Files
Test_AI/benchmark/utils.py

137 lines
3.5 KiB
Python
Raw Permalink Normal View History

2026-01-20 10:54:30 +08:00
"""
工具函数模块
"""
import hashlib
import os
import time
import logging
from typing import Optional, List
from pathlib import Path
from datetime import datetime
import numpy as np
def setup_logging(
level: int = logging.INFO,
log_file: Optional[str] = None,
format_str: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
) -> logging.Logger:
"""设置日志配置"""
logger = logging.getLogger("benchmark")
if logger.handlers:
return logger
logger.setLevel(level)
formatter = logging.Formatter(format_str)
console_handler = logging.StreamHandler()
console_handler.setLevel(level)
console_handler.setFormatter(formatter)
logger.addHandler(console_handler)
if log_file:
file_handler = logging.FileHandler(log_file, encoding="utf-8")
file_handler.setLevel(level)
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
return logger
def get_file_hash(file_path: str, algorithm: str = "md5") -> str:
"""计算文件哈希值"""
hash_func = hashlib.new(algorithm)
with open(file_path, "rb") as f:
for chunk in iter(lambda: f.read(8192), b""):
hash_func.update(chunk)
return hash_func.hexdigest()
def ensure_dir(path: str) -> str:
"""确保目录存在"""
Path(path).mkdir(parents=True, exist_ok=True)
return path
def get_timestamp() -> str:
"""获取当前时间戳字符串"""
return datetime.now().strftime("%Y%m%d_%H%M%S")
def format_duration(seconds: float) -> str:
"""格式化时间长度"""
if seconds < 60:
return f"{seconds:.1f}s"
elif seconds < 3600:
minutes = int(seconds // 60)
secs = seconds % 60
return f"{minutes}m {secs:.1f}s"
else:
hours = int(seconds // 3600)
minutes = int((seconds % 3600) // 60)
return f"{hours}h {minutes}m"
def calculate_statistics(data: List[float]) -> dict:
"""计算统计值"""
if not data:
return {"avg": 0.0, "min": 0.0, "max": 0.0, "p95": 0.0, "p99": 0.0, "std": 0.0}
arr = np.array(data)
return {
"avg": float(np.mean(arr)),
"min": float(np.min(arr)),
"max": float(np.max(arr)),
"p95": float(np.percentile(arr, 95)),
"p99": float(np.percentile(arr, 99)),
"std": float(np.std(arr)),
}
class Timer:
"""计时器上下文管理器"""
def __init__(self, name: str = ""):
self.name = name
self.elapsed = 0.0
def __enter__(self):
self.start_time = time.perf_counter()
return self
def __exit__(self, *args):
self.elapsed = time.perf_counter() - self.start_time
@property
def elapsed_ms(self) -> float:
return self.elapsed * 1000
class RateCounter:
"""速率计数器"""
def __init__(self, window_size: int = 100):
self.window_size = window_size
self.timestamps: List[float] = []
self.counts: List[int] = []
def tick(self, count: int = 1):
now = time.time()
self.timestamps.append(now)
self.counts.append(count)
while len(self.timestamps) > self.window_size:
self.timestamps.pop(0)
self.counts.pop(0)
def get_rate(self) -> float:
if len(self.timestamps) < 2:
return 0.0
duration = self.timestamps[-1] - self.timestamps[0]
if duration <= 0:
return 0.0
return sum(self.counts) / duration
def reset(self):
self.timestamps.clear()
self.counts.clear()