leaf-perfmon 1.0.0
Lightweight, extensible Python performance profiler with minimal overhead
License: MIT
Requires Python: >=3.7
Keywords: profiler, performance, monitoring, memory, cpu, io, lock, gc

# leaf_perfmon — Python 性能检测库
https://img.shields.io/badge/python-3.7+-blue.svg

https://img.shields.io/pypi/v/perfmon.svg

https://img.shields.io/badge/License-MIT-yellow.svg

https://img.shields.io/badge/code%2520style-black-000000.svg

perfmon 是一个轻量、高性能、可扩展的 Python 性能检测库，提供函数级、代码块级乃至文件级的性能剖析。
它不仅测量执行时间、内存占用、CPU 时间，还支持 I/O 等待时间、锁竞争、异常统计、GC 暂停、HTTP 请求详情、缓存命中率 等高级指标。
通过灵活的采样、阈值过滤、轻量模式，perfmon 能在生产环境中以极低的开销运行。

## ✨ 核心特性
### 多粒度检测：

装饰器（函数/方法）、上下文管理器（任意代码块）、文件级执行。

### 全面指标：

### 基础：

耗时、CPU 时间、内存分配（增量 & 峰值）、调用次数。

### 扩展：

文件读写 I/O、锁等待（threading/asyncio）、异常类型统计、GC 暂停、HTTP 请求（requests）、缓存命中率。

### 资源（需 psutil）：

CPU 使用率、进程内存 RSS。

### 低开销设计：

全局开关（零开销短路）

采样统计（按比例跳过检测）

轻量模式（不记录 min/max/avg）

慢调用阈值（只记录耗时超限的调用）

### 调用树追踪：

自动记录父子调用关系，直观呈现函数调用图。

### 异步/生成器友好：

完整支持 async def 和生成器函数。

### 导出功能：

JSON / CSV 格式导出，便于二次分析或可视化。

### 零依赖核心：

仅需 Python 标准库（扩展指标需相应库时可选）。

## 📦 安装
bash
````
pip install perfmon
````
可选依赖（用于部分扩展指标）：

bash
````
pip install perfmon[psutil]     # 资源监控（CPU 利用率、内存 RSS）
pip install perfmon[requests]   # HTTP 请求监控
pip install perfmon[full]       # 安装所有扩展
````
## 🚀 快速入门
1️⃣ 检测函数
python
````
import perfmon as pm
import time

@pm.profile(memory=True, cpu=True)
def slow_function():
    time.sleep(0.1)
    return sum(range(10**6))

slow_function()
pm.report()   # 打印性能统计表格
````
输出示例：

text
````
名称                           调用   总时(s)    平均(s)    最小(s)    最大(s)    总CPU(s)   平均CPU   最小CPU   最大CPU   内存(B)    峰值(B)    CPU%  
----------------------------------------------------------------------------------------------------------------------------------
slow_function                  1      0.10123    0.10123    0.10123    0.10123    0.02001    0.02001   0.02001   0.02001   2048      8192      12.5  
````
2️⃣ 检测代码块
python
````
with pm.profile_context("数据加载", memory=True):
    data = [i**2 for i in range(100000)]
````
3️⃣ 检测整个脚本
python
````
pm.profile_file("my_script.py", measure_time=True, memory=True)
pm.report()
````
4️⃣ 导出 JSON 报告
python
````
pm.export_json("perf_results.json")
````
## 📚 详细使用指南
### 🔹 装饰器 @profile
python
````
@pm.profile(
    name=None,           # 自定义显示名称（默认函数限定名）
    measure_time=True,   # 测量耗时
    memory=False,        # 测量内存分配（需 tracemalloc）
    cpu=False,           # 测量 CPU 时间
    lite_mode=None,      # 局部轻量模式（覆盖全局）
    sample_rate=None,    # 局部采样率（覆盖全局）
    slow_threshold=None  # 局部慢调用阈值（覆盖全局）
)
````
支持：普通函数、异步函数、生成器函数。

自动记录：调用次数、耗时（若开启）、CPU 时间（若开启）、内存增量/峰值（若开启）、异常类型（若全局配置 monitor_exceptions=True）。

### 🔹 缓存命中率装饰器 @profile_cache
python
````
@pm.profile_cache(maxsize=128)
def expensive_func(n):
    # 计算结果并缓存
    return n * n
````
自动统计缓存命中/未命中次数。

需通过 pm.configure(monitor_cache=True) 启用记录到 perfmon 统计中。

### 🔹 上下文管理器 profile_context
python
````
with pm.profile_context(
    name,                # 代码块名称
    measure_time=True,
    memory=False,
    cpu=False
):
    # 你的代码块
````
同样支持异步上下文管理器（async with）。


### 🔹 文件级检测 profile_file
python
````
pm.profile_file(filename, measure_time=True, memory=False, cpu=False)
````
执行指定 Python 文件，并将其整体作为一个检测项（名称为 file:文件名）。

### 🔹 全局配置 configure
python
````
pm.configure(
    # 基本设置
    lite_mode=False,           # 轻量模式（不记录 min/max/avg）
    sample_rate=1.0,           # 采样率 0.0~1.0
    slow_threshold=0.0,        # 慢调用阈值（秒）
    record_parent=True,        # 记录调用者（调用树）
    record_children=True,      # 记录子调用（调用树）
    resource_monitor=False,    # 启用资源监控（需 psutil）

    # 扩展指标开关（默认 False）
    monitor_io=False,          # 文件 I/O 等待时间
    monitor_locks=False,       # 锁等待时间
    monitor_exceptions=False,  # 异常类型统计
    monitor_gc=False,          # GC 暂停时间
    monitor_http=False,        # HTTP 请求详情（需 requests）
    monitor_cache=False        # 缓存命中率（配合 @profile_cache）
)
````
所有开关均可动态修改，且修改后立即生效。

### 🔹 控制开关
python
````
pm.enable()   # 全局启用检测（默认）
pm.disable()  # 全局禁用检测（零开销）
pm.reset()    # 清空所有已收集的统计信息
````
### 🔹 报告与导出
python
````
pm.report(sort_by='total_time')   # 打印统计表格，可按任意列排序

pm.export_json("path/to/file.json")   # 导出全部指标为 JSON
pm.export_csv("path/to/file.csv")     # 导出主要指标为 CSV
````
### 📊 检测指标详解
指标分类	指标名称	说明	启用方式

基础	调用次数	函数/代码块被执行次数	始终记录

总耗时 / 平均 / 最小 / 最大	墙钟时间（秒）	measure_time=True

CPU 时间	进程 CPU 时间（秒）	cpu=True

内存增量	执行期间内存分配净增量（字节）	memory=True

内存峰值	执行期间内存分配峰值（字节）	memory=True

扩展	I/O 读耗时	文件读操作累计耗时（秒）	configure(monitor_io=True)

I/O 写耗时	文件写操作累计耗时（秒）	同上

锁等待时间	threading.Lock / asyncio.Lock 获取等待时间	configure(monitor_locks=True)

异常统计	被检测函数抛出的异常类型及次数	configure(monitor_exceptions=True)

GC 暂停时间	垃圾回收器执行耗时（累计）	configure(monitor_gc=True)

HTTP 请求	每个 URL 的请求次数、总耗时、状态码分布（需 requests）	configure(monitor_http=True)

缓存命中率	被 @profile_cache 装饰的函数命中/未命中次数	configure(monitor_cache=True)

资源	CPU 利用率	执行期间平均 CPU 使用率（%），需 psutil 且 resource_monitor=True	resource_monitor=True

进程内存 RSS	进程常驻内存（字节），需 psutil	同上

调用树	父函数数	调用该函数的不同父函数数量	record_parent=True

子调用总数	该函数调用的其他函数总次数	record_children=True

所有扩展指标默认关闭，确保零额外性能开销。仅在需要时显式开启。

## 🧠 高级功能
1️⃣ 轻量模式 (lite_mode=True)

不再记录 min_time / max_time / min_cpu / max_cpu。

减少约 30% 的内存占用和计算开销。

2️⃣ 采样统计 (sample_rate=0.1)

只有 10% 的调用会被真正检测并记录。

适用于极高频率调用的函数（如每毫秒执行一次）。

3️⃣ 慢调用阈值 (slow_threshold=0.01)

只记录耗时超过 0.01 秒的调用。

自动过滤掉绝大多数快速调用，聚焦性能瓶颈。

4️⃣ 调用树追踪

通过 record_parent / record_children 控制。

在报告表格中显示 父函数数 和 子调用总数，快速识别热点路径。

5️⃣ 资源监控 (需 psutil)

在装饰器/上下文管理器开启时，额外记录 CPU 利用率 (%) 和 进程内存 RSS。

报告表格中增加 CPU% 列。

## ⚡ 性能开销说明
perfmon 在设计时始终将 低开销 作为首要目标：

全局禁用：pm.disable() 后，所有装饰器直接返回原函数，无任何额外函数调用。

采样：未命中采样的调用不执行任何测量代码。

轻量模式：跳过 min/max 更新，减少数据存储操作。

零依赖核心：基础指标仅使用 Python 内置模块。

在典型场景下（仅开启时间测量），每个函数调用增加约 200~400ns 开销。
开启内存检测会增加约 1~2µs（取决于 tracemalloc）。
扩展指标（I/O、锁等）仅在对应操作发生时产生额外开销。

## 🧩 扩展指南
perfmon 的设计易于扩展，您可以在 StatEntry 中添加新字段，在 Profiler.record 方法中增加参数，并在适当位置（如补丁函数、装饰器）调用 record 传递新指标。

在 StatEntry.__slots__ 和 __init__ 中添加新字段。

在 Profiler.record 方法中添加对应参数并记录到 stat。

在需要采集数据的地方（如补丁函数、装饰器）调用 _PROFILER.record(...) 传递新指标。

在 export_json 和 export_csv 中添加导出逻辑。

示例：添加“数据库查询耗时”指标可参考 I/O 监控的实现。

## 📝 完整示例
示例1：综合检测（开启所有扩展）
python
````
import perfmon as pm
import threading, requests, time

pm.configure(
    monitor_io=True,
    monitor_locks=True,
    monitor_exceptions=True,
    monitor_gc=True,
    monitor_http=True,
    monitor_cache=True,
    resource_monitor=True
)

@pm.profile(memory=True, cpu=True)
def worker():
    # 文件 I/O
    with open('/tmp/test.txt', 'w') as f:
        f.write('x' * 10000)
    # 锁等待
    lock = threading.Lock()
    lock.acquire()
    lock.release()
    # HTTP 请求
    requests.get('https://httpbin.org/get')
    # 异常
    try:
        1/0
    except ZeroDivisionError:
        pass

worker()
pm.report()
pm.export_json('full_report.json')
````
示例2：缓存命中率统计
python
````
@pm.profile_cache(maxsize=5)
@pm.profile()   # 双层装饰器，顺序无妨
def fib(n):
    return n if n < 2 else fib(n-1) + fib(n-2)

fib(10)
fib(10)   # 第二次命中缓存
print(fib.cache_info())   # 直接查看缓存统计
pm.report()   # 缓存命中/未命中会出现在表格中
````
示例3：采样 + 轻量模式
python
````
pm.configure(lite_mode=True, sample_rate=0.2)

@pm.profile()
def fast():
    for _ in range(1000):
        pass

for _ in range(1000):
    fast()

pm.report()   # 只记录了约200次调用，且无 min/max 列
````
## 📋 API 参考
### 全局函数

函数	描述

profile(...)	函数性能检测装饰器

profile_cache(maxsize=128)	缓存命中率检测装饰器

profile_context(name, ...)	代码块上下文管理器

profile_file(filename, ...)	执行并检测整个 Python 文件

configure(...)	动态修改全局配置

enable() / disable()	全局启用/禁用检测

reset()	清空所有统计数据

report(sort_by='total_time')	打印统计表格

export_json(filepath) / export_csv(filepath)	导出统计数据到文件

### 配置项详解
配置参数	类型	默认值	说明

lite_mode	bool	False	轻量模式

sample_rate	float	1.0	采样率 0.0~1.0

slow_threshold	float	0.0	慢调用阈值（秒）

record_parent	bool	True	记录调用者

record_children	bool	True	记录子调用

resource_monitor	bool	False	启用 psutil 资源监控

monitor_io	bool	False	监控文件 I/O 耗时

monitor_locks	bool	False	监控锁等待时间

monitor_exceptions	bool	False	监控异常类型

monitor_gc	bool	False	监控 GC 暂停

monitor_http	bool	False	监控 HTTP 请求（需 requests）

monitor_cache	bool	False	监控缓存命中率（配合 profile_cache）

## 🤝 贡献指南
欢迎贡献代码、报告问题或提出新功能建议！

你可以将贡献的代码发给我，Email：FourWaterLeaf@163.com

## 许可证
MIT