AnnasMazhar/PyPerfOptimizer
GitHub: AnnasMazhar/PyPerfOptimizer
一款专注 Python 性能反模式检测与自动修复的工具,能捕获其他 linter 遗漏的未编译正则和列表成员测试模式,并提供验证加速效果。
Stars: 0 | Forks: 0
# PyPerfOptimizer
一款能够捕获其他工具无法捕获的模式,并自动修复它们的 Python 性能检查工具。
## 功能说明
检测代码中未编译的正则表达式以及将列表作为集合进行成员测试的模式。自动修复这些模式并经过验证可带来 2 倍的加速提升。可作为 linter 使用(发现问题时退出代码为 1),适用于 CI/pre-commit 场景。
**其他 Python linter(Ruff、Pylint、Flake8)均无法捕获这些模式。** 通过在相同代码上启用所有规则运行所有工具进行了验证。
## 安装
```
pip install pyperfoptimizer
```
## 使用说明
### 扫描 (lint 模式)
```
$ pyperfoptimizer scan myapp.py
```
```
━━━ Source Fixes (auto-fixable) ━━━━━━━━━━━━━━━━━━━━━━━━━━
myapp.py:6 membership_test_set 2-4x
myapp.py:8 regex_precompile 2-10x for hot paths
━━━ Compilation Candidates ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
myapp.py:3 process_users blocked
Status: blocked (not all parameters have numeric type annotations)
━━━ Architecture Suggestions ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
No architecture suggestions.
```
发现问题时退出代码为 1,代码无问题时为 0。可在 CI 中使用。
### 修复 (自动应用)
```
$ pyperfoptimizer fix myapp.py
Written to: myapp.optimized.py
```
**修复前:**
```
import re
def process_users(users):
results = []
for user in users:
if user["role"] in ["admin", "editor", "moderator", "reviewer", "manager"]:
name = user["first"] + " " + user["last"]
if re.match(r"^[A-Z]", name):
results.append({"name": name, "role": user["role"]})
return results
```
**修复后(自动处理):**
```
import re
_RE_0 = re.compile(r"^[A-Z]")
def process_users(users):
results = []
for user in users:
if user["role"] in {"admin", "editor", "moderator", "reviewer", "manager"}:
name = user["first"] + " " + user["last"]
if _RE_0.match(name):
results.append({"name": name, "role": user["role"]})
return results
```
### 验证 (证明它更快)
```
$ pyperfoptimizer fix --verify myapp.py
Written to: myapp.optimized.py
Speedup: 1.34x | PASS
```
使用测试数据对函数进行基准测试。报告 PASS(>1.1×)或 FAIL。
### Pre-commit 钩子
```
# .pre-commit-config.yaml
repos:
- repo: https://github.com/AnnasMazhar/PyPerfOptimizer
rev: v0.2.1
hooks:
- id: pyperfoptimizer
entry: pyperfoptimizer scan
types: [python]
```
### Profile 引导 (关注热点路径)
```
$ py-spy record -o profile.json -- python myapp.py
$ pyperfoptimizer scan myapp.py --profile profile.json
```
仅报告消耗大量 CPU 时间的函数中存在的问题。
## 已验证的加速效果
使用 `python3 -m timeit` 测量,Python 3.12 环境:
```
re.match(pattern, s) vs compiled.match(s): 510ns → 208ns = 2.45×
x in [5 literals] vs x in {5 literals}: varies by size, 1.9-4.2×
```
在 FastAPI、Flask、Django、Strands SDK 的 76 个文件上进行了测试:**0 次报错**。
## 本工具能捕获而其他工具无法捕获的内容
| 模式 | Ruff | Pylint | Flake8 | **PyPerfOptimizer** |
|---------|------|--------|--------|---------------------|
| 函数内的 `re.match(string, x)` | ✗ | ✗ | ✗ | **✓ 自动修复** |
| `x in [literal, literal, ...]` | ✗ | ✗ | ✗ | **✓ 自动修复** |
通过在同一个文件上运行 `ruff check --select ALL`、`pylint` 和 `flake8+perflint` 进行了验证。它们均未给出任何警告。
## 本工具不适用的情况
- 不是通用的 Python 加速器(CPython 3.11+ 已经优化了大多数微模式)
- 不是性能分析器(请使用 py-spy 或 Scalene,然后使用 `--profile` 将输出结果提供给本工具)
- 不是编译器(对于类型化的计算密集型代码,请使用 mypyc)
## 核心发现
CPython 内部会缓存已编译的正则表达式(最多 512 个模式)。2 倍的加速来源于消除了**缓存查找开销**(字典键的创建 + 哈希 + 比较),而不是避免了重新编译。在频繁执行的热循环中,这种开销会不断累积。
## 参与贡献
135 个测试:`python -m pytest tests/ -v`
## 许可证
MIT
标签:Flake8, Linter, pptx, Pre-commit, Pylint, Python, Python性能调优, Ruff, SOC Prime, 代码审查, 代码重构, 开发工具, 性能优化, 性能分析, 无后门, 检测绕过, 模块化设计, 正则表达式预编译, 自动化修复, 逆向工具, 错误基检测, 集合转换, 静态代码分析