Skip to main content

Lightweight, extensible Python performance profiler with minimal overhead

Project description

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 内置模块。

在典型场景下(仅开启时间测量),每个函数调用增加约 200400ns 开销。 开启内存检测会增加约 12µs(取决于 tracemalloc)。 扩展指标(I/O、锁等)仅在对应操作发生时产生额外开销。

🧩 扩展指南

perfmon 的设计易于扩展,您可以在 StatEntry 中添加新字段,在 Profiler.record 方法中增加参数,并在适当位置(如补丁函数、装饰器)调用 record 传递新指标。

在 StatEntry.slotsinit 中添加新字段。

在 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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

leaf_perfmon-1.0.0.tar.gz (18.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

leaf_perfmon-1.0.0-py3-none-any.whl (13.8 kB view details)

Uploaded Python 3

File details

Details for the file leaf_perfmon-1.0.0.tar.gz.

File metadata

  • Download URL: leaf_perfmon-1.0.0.tar.gz
  • Upload date:
  • Size: 18.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for leaf_perfmon-1.0.0.tar.gz
Algorithm Hash digest
SHA256 97809c753ee49e7fadbb7b5f45e2da55e508e225fca28d811d2aca4935277d56
MD5 9f61b275e5ead5542a95d446b8c27f01
BLAKE2b-256 32c5a86fefcb7b6f3716d81618a999f5fbcdcc97504b4016d49a2a9ff4df973d

See more details on using hashes here.

File details

Details for the file leaf_perfmon-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: leaf_perfmon-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 13.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for leaf_perfmon-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 841882c49b5a420eeb3f1d9c02e219f8ae9c48e32b17fa33e34704ec53a6da82
MD5 a751973e0e7e3f1772aa93842bc188d5
BLAKE2b-256 0dea3225a2b191153f4caa87e1e27b9a5e02f572674f9b2bbadaa4ff1b0d775e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page