关于 performance-review
通过静态分析检查代码中的时间和空间复杂度热点。始终扫描 Python;安装可选依赖后,可扩展到指定语言和调用图分析。
主要功能
- 01使用标准库 AST 扫描 Python
- 02检测时间与空间复杂度热点
- 03可选扫描 JS/TS 等语言
- 04根据调用图数据提升严重级别
- 05生成分类 Markdown 发现报告
适用场景
- 01合并前审查变更代码
- 02排查疑似运行缓慢的函数
- 03检查重构是否引入二次复杂度模式
- 04检查 AI 生成代码中的嵌套循环热点
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ athola/ claude-night-market --skill performance-review安装后在 Claude Code 中输入/performance-review确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
modules/gauntlet-integration.mdkuva-visualization.mdmemory-allocation-lenses.mdspace-complexity.mdtime-complexity.md详细介绍
性能审查
对时间和空间复杂度热点进行静态分析审查。
该技能分为三个逐步增强的层级。第 1 层使用 Python 标准库中的
ast,始终运行。安装 tiers
扩展后,第 2 层使用 tree-sitter,将检测范围扩展到 JS/TS、Go、Rust、Java 和 C/C++。第 3 层从每项发现出发,沿 gauntlet 调用图向前遍历;若被调用函数存在热点,则将其严重性提升一级。当 gauntlet 插件可导入且存在 .gauntlet/graph.db 时运行。缺少这些条件时,第 2 层和第 3 层不执行,第 1 层仍会对 Python 源码生成发现结果。
快速开始
/performance-review # scan changed files
/performance-review path/to/file.py # scan one file
/performance-review --tier 1 # force Tier 1 only
以编程方式使用:
from pensive.skills.performance_review import PerformanceReviewSkill
skill = PerformanceReviewSkill()
result = skill.analyze(context, "src/module.py")
for f in result.issues:
print(f"[{f.severity}] {f.file}:{f.line} {f.message}")
适用场景
- 在合并前审查会处理随用户规模增长的数据的代码。
- 在使用性能分析器之前,排查某个函数为何「感觉很慢」。
- 审查重构是否引入了新的 O(n²) 模式。
- 为 AI 生成的代码设置防护措施,因为其中常见嵌套循环热点。
不适用场景
- 目标是进行运行时测量(内存分析、真实数据上的 CPU 耗时)。请改用
Skill(parseltongue:python-performance): 该技能会运行cProfile、py-spy和基准测试。 - 不专注于热点的一般重构指导:请使用
Skill(pensive:code-refinement),其algorithm-efficiency模块涵盖更广泛的优化模式。此技能负责检测;该技能负责讲解。 - 判断手动编写的循环变换(循环展开、手动 SIMD、强度削弱)是否值得保留:请使用
Skill(leyline:loop-optimization),了解手动优化与编译器优化的取舍规则。 此技能标记热点形态,而非变换方案。 - 架构层面的性能问题(分片、缓存层、队列位置):请使用
Skill(pensive:architecture-review)。
必需的进度项
perf-review:context-establishedperf-review:scan-completeperf-review:findings-categorizedperf-review:integration-checkedperf-review:report-generatedperf-review:findings-verified
工作流
第 1 步:上下文(perf-review:context-established)
- 确定目标文件。若调用时未提供参数,则使用
git diff --name-only。若提供了路径,则限定在该路径范围内。 - 记录涉及的语言。第 1 层覆盖 Python;非 Python 文件需要安装
tiers扩展才能由第 2 层覆盖。
第 2 步:第 1 层 AST 扫描(perf-review:scan-complete)
加载 modules/time-complexity.md 以查看时间复杂度模式,并加载
modules/space-complexity.md 以查看空间复杂度模式。每个模块
都会记录各检测器对应的 AST 形态。
在自动扫描的同时,加载
modules/memory-allocation-lenses.md,并通过阅读目标文件应用其中的三个
手动检查视角(无界外部来源集合、热点路径重复计算、串行阻塞 I/O)。
对于每个 Python 目标文件,调用:
from pensive.skills.performance_review import PerformanceReviewSkill
result = PerformanceReviewSkill().analyze(context, path)
访问器会遍历一次 AST,并生成 ReviewFinding 记录。
第 3 步:分类并排序(perf-review:findings-categorized)
按严重性对发现结果分组:
- HIGH:作用于输入规模迭代对象的 O(n²) 或更差复杂度(T1、T2)。
- MEDIUM:无界分配或每次迭代的开销(T3、T4、S1、S3)。
- LOW:风格层面的低效写法(T5、T6、S2)。
- CRITICAL:保留给第 3 层的传递升级。
在同一严重性组内,按文件和行号排序。在目标模块加载时,忽略用户已明确标记为可接受的发现(TODO/注释标记)。
第 4 步:Tier 2/3 增强(perf-review:integration-checked)
加载 modules/gauntlet-integration.md 以了解契约。
如果可以导入 tree_sitter_language_pack,则对第 2 步跳过的非 Python 文件运行 Tier 2。如果可以导入 gauntlet,且扫描文件所在目录或任一父目录中存在 .gauntlet/graph.db,则运行 Tier 3,根据传递调用链中的热点提升严重级别。
如果没有安装额外依赖,此步骤不会执行任何操作,报告会注明“Tier 2/3 不可用:安装带有 tiers extra 的 pensive,以支持多语言和调用链覆盖。”无法由 tree-sitter 解析的文件会添加警告,且不会产生 Tier 2 发现。
第 5 步:生成报告(perf-review:report-generated)
生成 Markdown 报告:
## Performance Review: <target>
### HIGH (<count>)
- src/foo.py:42: Nested loop over the same iterable 'items'.
Suggestion: sort + two pointers, or hash-set membership.
### MEDIUM (<count>)
- ...
### LOW (<count>)
- ...
Tier coverage: 1 (always) | 2 (gauntlet ✓/✗) | 3 (graph ✓/✗)
报告仅供参考。请通过 Skill(pensive:code-refinement) 应用修复,或手动合并。
分层分析
| 层级 | 来源 | 运行时机 | 覆盖范围 |
|---|---|---|---|
| 1 | 标准库 ast | 始终运行(仅限 Python 源代码) | T1-T6、S1-S3 |
| 2 | tree_sitter_language_pack | 可导入时,对非 Python 文件运行 | JS/TS、Go、Rust、Java、C/C++ 上的 T1、T2、S1(Java 和 C:仅 T1) |
| 3 | gauntlet.graph.GraphStore | 可导入且在文件上层找到 .gauntlet/graph.db 时运行 | 当可通过 CALLS 到达的函数包含热点时,提升一级严重级别 |
输出格式
发现项使用来自 pensive.skills.base 的共享 ReviewFinding 数据类:
ReviewFinding(
file="src/module.py",
line=42,
severity="HIGH", # LOW | MEDIUM | HIGH | CRITICAL
category="time", # time | space
message="Nested loop over the same iterable 'items'.",
suggestion="Sort + two pointers, or hash-set membership.",
anchor="verbatim source text at file:line",
code_snippet="",
)
此结构与 pensive 的其他审查技能一致,因此发现项无需转换即可传入 Skill(pensive:unified-review)。
跨插件依赖项
| 依赖项 | 是否必需? | 缺失时的影响 |
|---|---|---|
tree_sitter_language_pack | 可选(tiers extra) | Tier 2 返回 [];Python 覆盖范围不变 |
gauntlet.graph.GraphStore | 可选(gauntlet 插件,不在 PyPI 上) | Tier 3 返回 [];不会提升严重级别 |
可选导入契约沿用了 plugins/leyline/src/leyline/tokens.py:25-32 中的先例:尝试导入并赋值给模块级哨兵,然后在每个层级辅助函数中遇到 None 时提前返回。plugins/gauntlet/hooks/precommit_gate.py:35-40 是同一结构的布尔标志变体。具体代码结构请参阅 modules/gauntlet-integration.md。
支持模块
modules/time-complexity.md:T1-T6 检测器模式和 AST 结构。modules/space-complexity.md:S1-S3 检测器模式。modules/gauntlet-integration.md:Tier 2/3 契约、回退语义和示例。modules/kuva-visualization.md:使用 kuva 将基准测试数据渲染为图表(criterion、pytest-benchmark、临时表格)。说明图表证据在何种情况下满足工作证明要求。modules/memory-allocation-lenses.md:手动审查视角(非 AST 检测器),用于检查从外部来源填充的无界集合、应进行记忆化的热路径重复计算,以及针对无界集合的串行阻塞 I/O。需通过阅读代码来应用这些视角;Testing 中的检测器测试规则不涵盖这些内容,因为它们没有自动化。
验证
只有调用方能够确认 perf-review 发现确实存在时,它才有用。在将任何发现视为值得修复之前,请使用此检查清单:
- 在分析器下复现。 在热点上运行
cProfile、py-spy或特定语言的等效工具。发现会指出 AST 形状;分析器则会验证运行时影响。 - 重新运行失败的基准测试。 如果存在
benches/,热点应该体现在数据中,而不只是 AST 扫描结果中。 - 比较拟议修复前后的数据。 如果数据没有变化,说明修复有误。将修复前后的计时结果分别记录为
[E1](修复前)和[E2](修复后)等证据引用。如果有 3 个或更多数据点,请生成 kuva 图表并附在 PR 中(参见modules/kuva-visualization.md)。 - 手动抽查 2 或 3 个报告的热点。 当调用方短路执行时,某些发现可能在 AST 层面成立,但在调用图层面并不成立。手动抽查可以发现这一点。
Skill(imbue:proof-of-work) 的规范同样适用:像“热点已修复”这样的说法需要证据,而非断言。
测试
plugins/pensive/tests/skills/test_performance_review.py 中已有一个测试文件,用于覆盖 AST 形状检测器。此处的更改需遵循两条规则:
- 新增检测器时添加测试。 添加到模块中的任何新 T-* 或 S-* 模式都必须附带一个能触发该模式的最小 AST 示例测试。
- 移除任何误报时添加回归测试。 当技能不再将某个过去看起来像热点的形状报告为问题时,应将原因写入测试用例,以便日后发现回归。
Iron Law 同样适用:新增检测器却没有先编写失败测试,就等于要求在代码分析组件中跳过 TDD;而这里恰恰是 TDD 最能发挥作用的地方。
验证发现有据可依(perf-review:findings-verified)
将发现写入 .review/findings.json,运行引用验证器(Skill(imbue:review-core) 步骤 5),并删除验证器拒绝的发现,或将其标记为 UNVERIFIED。
退出标准
- 存在针对所请求目标的 perf-review 报告文件。
- 每项发现都带有严重性标签,以及调用方可据此采取行动的具体建议。
- 已运行时间复杂度(T1-T6)和空间复杂度(S1-S3)检测器;并报告了层级覆盖情况。
- 第 2 层(tree-sitter)和第 3 层(图存储)的契约遵守可选导入哨兵规则:缺少模块时返回
[],而不是抛出异常。 - 每个新检测器都附带一个最小 AST 测试,该测试在检测器存在之前会失败;每个已移除的误报都附带一个回归测试。
- 从统一入口调用时,发现无需转换即可流入
Skill(pensive:unified-review)。 - 每项报告的发现都带有经
citation_verifier.py确认的Location和逐字Anchor(退出代码为0);否则,未验证的发现已被删除或标记为UNVERIFIED