```python
import time
import functools
from typing import Callable, Any
import logging
# 基礎版本的時間統計裝飾器
def timer(func: Callable) -> Callable:
基礎函數執行時間統計裝飾器
@functools.wraps(func)
def wrapper(args, kwargs) -> Any:
start_time = time.perf_counter()
result = func(args, kwargs)
end_time = time.perf_counter()
execution_time = end_time - start_time
print(f函數 {func.__name__} 執行耗時: {execution_time:.4f} 秒)
return result
return wrapper
# 帶參數的高級版本
def advanced_timer(unit: str = 'seconds', precision: int = 4) -> Callable:
支持不同時間單位和精度的裝飾器
def decorator(func: Callable) -> Callable:
@functools.wraps(func)
def wrapper(args, kwargs) -> Any:
start_time = time.perf_counter()
result = func(args, kwargs)
end_time = time.perf_counter()
execution_time = end_time - start_time
# 時間單位轉換
if unit == 'milliseconds':
execution_time = 1000
time_unit = '毫秒'
elif unit == 'microseconds':
execution_time = 1000000
time_unit = '微秒'
else:
time_unit = '秒'
print(f函數 {func.__name__} 執行耗時: {execution_time:.{precision}f} {time_unit})
return result
return wrapper
return decorator
# 基於類的裝飾器實現
class TimerClass:
基於類的計時裝飾器,支持累計統計
def __init__(self, func: Callable):
functools.update_wrapper(self, func)
self.func = func
self.total_time = 0.0
self.call_count = 0
def __call__(self, args, kwargs) -> Any:
start_time = time.perf_counter()
result = self.func(args, kwargs)
end_time = time.perf_counter()
execution_time = end_time - start_time
self.total_time += execution_time
self.call_count += 1
print(f函數 {self.func.__name__} 本次執行: {execution_time:.4f} 秒)
print(f累計執行: {self.call_count} 次, 總耗時: {self.total_time:.4f} 秒)
print(f平均耗時: {self.total_time/self.call_count:.4f} 秒)
return result
# 帶日誌記錄的時間統計
def logged_timer(logger_name: str = 'performance') -> Callable:
使用日誌記錄執行時間的裝飾器
def decorator(func: Callable) -> Callable:
logger = logging.getLogger(logger_name)
@functools.wraps(func)
def wrapper(args, kwargs) -> Any:
start_time = time.perf_counter()
result = func(args, kwargs)
end_time = time.perf_counter()
execution_time = end_time - start_time
logger.info(f函數 {func.__name__} 執行完成, 耗時: {execution_time:.6f} 秒)
return result
return wrapper
return decorator
# 上下文管理器版本的時間統計
class TimerContext:
上下文管理器形式的時間統計
def __init__(self, name: str = 操作):
self.name = name
self.start_time = None
self.end_time = None
def __enter__(self):
self.start_time = time.perf_counter()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.end_time = time.perf_counter()
execution_time = self.end_time - self.start_time
print(f{self.name} 耗時: {execution_time:.4f} 秒)
@property
def elapsed_time(self) -> float:
if self.start_time and self.end_time:
return self.end_time - self.start_time
elif self.start_time:
return time.perf_counter() - self.start_time
return 0.0
# 使用示例
if __name__ == __main__:
# 基礎裝飾器使用
@timer
def fibonacci(n: int) -> int:
if n <= 1:
return n
return fibonacci(n-1) + fibonacci(n-2)
# 高級裝飾器使用
@advanced_timer(unit='milliseconds', precision=2)
def heavy_computation(n: int) -> int:
return sum(ii for i in range(n))
# 類裝飾器使用
@TimerClass
def sample_function():
time.sleep(0.1)
return 完成
# 測試執行
print(=== 基礎裝飾器測試 ===)
fibonacci(5)
print(
=== 高級裝飾器測試 ===)
heavy_computation(1000000)
print(
=== 類裝飾器測試 ===)
sample_function()
sample_function()
print(
=== 上下文管理器測試 ===)
with TimerContext(數據處理):
time.sleep(0.2)
result = sum(range(100000))
print(f處理結果: {result})
```
裝飾器選擇指南:
1. 基礎需求:使用 `@timer` 裝飾器,簡單直接
2. 精確控制:使用 `@advanced_timer`,支持時間單位和精度調整
3. 統計分析:使用 `TimerClass`,提供累計統計功能
4. 生產環境:使用 `@logged_timer`,集成日誌系統
5. 代碼塊統計:使用 `TimerContext` 上下文管理器
性能優化建議:
- 使用 `time.perf_counter()` 而非 `time.time()`,提供更高精度
- 在裝飾器中使用 `functools.wraps` 保持函數元信息
- 對於高頻調用函數,考慮添加開關控制統計功能
- 在生產環境中使用異步日誌記錄避免性能影響
這種方法提供了靈活、可重用的性能監控解決方案,適用於不同場景的性能優化需求。