mcpField
C
codeprobe-performance

codeprobe-performance

github.com/machineroom-dev其他5109 次安装6 天前更新
代码仓库

关于 codeprobe-performance

面向审查代码库的开发者,用于发现性能与扩展性问题的代码审计技能。检查查询模式、内存使用、缓存、并发、算法效率和前端性能。

主要功能

  1. 01检测 N+1 与无界查询
  2. 02检查索引和缓存行为
  3. 03标记内存与算法效率问题
  4. 04审查并发风险
  5. 05发现前端性能问题

适用场景

  1. 01审计请求路径的查询开销
  2. 02检查大型数据集处理方式
  3. 03检查缓存失效与任务幂等性
  4. 04定位高开销的前端渲染或导入

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/machineroom-dev/codeprobe --skill codeprobe-performance

安装后在 Claude Code 中输入/codeprobe-performance确认已加载。

详细介绍

独立模式

如果直接调用(而非通过编排器调用),必须先:

  1. 阅读 ../codeprobe/shared-preamble.md(相对于此 SKILL.md 的位置解析——即同级的 codeprobe 技能目录,而非用户的项目),了解输出约定、执行模式和限制。
  2. 根据项目的技术栈,加载 ../codeprobe/references/ 中适用的参考文件(按相同方式解析路径)。
  3. 除非用户另有指定,否则默认使用 full 模式。

性能与可扩展性审计器

范围

此子技能会检测以下类别的性能与可扩展性问题:

  1. N+1 查询 — 在循环中延迟加载关联
  2. 缺少索引 — 在未建立索引的列上执行 WHERE/ORDER BY
  3. 无界查询 — 未分页或限制结果的 Model::all()
  4. 内存 — 将整个文件加载到内存中、在循环中累积数组
  5. 缓存 — 重复执行相同查询、缺少 TTL、写入后缓存过期
  6. 算法效率 — 热路径中的 O(n^2)、嵌套循环、在循环中排序
  7. 并发 — 竞态条件、非幂等队列任务、共享可变状态
  8. 前端性能 — 不必要的重新渲染、包体积、缺少延迟加载

不会标记的问题

  • 非热路径代码中的过早优化 — 应按比例进行设计。启动时只调用一次的工具函数,不需要像请求处理程序一样优化。
  • 仅用于开发的调试查询 — 在数据填充器、仅供开发使用的命令或调试端点中的查询。
  • 批处理脚本 — 有意处理所有数据的脚本(迁移、数据回填),此类脚本使用无界查询可能是合理的。
  • 小型且有界的集合(<100 项)上的 O(n^2) — 对已知小型数组执行嵌套循环没有问题。
  • 前端 SSR/构建时代码 — 服务端组件和构建脚本的性能特征与客户端代码不同。

检测说明

N+1 查询
ID 前缀检测内容检测方法严重性
PERF在循环中访问 Eloquent 关联,但未进行预加载搜索遍历集合的 foreach/for 循环,然后检查循环体内是否访问关联属性(例如 $order->items、$user->profile)。检查生成该集合的查询是否使用了 with() 或 load() 加载该关联。Major
PERF迭代期间发生任何 ORM 延迟加载查找在循环中隐式触发数据库查询的模式:Django QuerySet 在每次迭代时访问、SQLAlchemy 延迟加载、在 .map() 中访问 Prisma 关联。Major
PERF模板/视图触发查询Blade 模板、Jinja2 模板或 React 组件在渲染期间调用会触发查询的关联属性。Major
缺少索引
ID 前缀检测内容检测方法严重性
PERF在未建立索引的列上执行 WHERE/ORDER BY对照迁移文件或架构定义,检查查询条件(where()、orderBy()、WHERE、ORDER BY)是否有匹配的索引。Major
PERF外键未建立索引检查迁移文件中的 foreignId()、foreign()、references() 是否有对应的索引定义。大多数 ORM 会自动添加这些索引,但原始迁移可能会遗漏。Minor
PERF需要复合索引的组合查询同一查询中对不同列使用多个 where() 条件,或使用 where() + orderBy() 组合;这类查询可从复合索引中受益。Minor
无界查询
ID 前缀检测内容检测方法严重程度
PERFModel::all() 或不带限制的 SELECT *搜索 .all()、::all()、findAll()、不带 LIMIT 的 SELECT * FROM、paginate()、take() 或 limit()。重大
PERF处理大型数据集时缺少游标/分块处理大型数据集时,调用 get() 或加载整个集合的操作。应使用 cursor()、chunk()、lazy() 或等效的流式处理方式。重大
内存
ID 前缀检测内容检测方法严重程度
PERF将整个文件加载到内存中对用户上传的文件或大型文件调用 file_get_contents(),对大小可变的文件调用 fs.readFileSync(),以及不限制读取大小的 Python open().read()。重大
PERF在循环中累积数组在循环中不断增长且没有上限或清理机制的数组——在内存中收集本可通过流式处理或生成方式处理的结果。次要
PERF使用大型集合而非生成器对于大型数据集,返回完整数组/列表,而使用生成器(yield)、惰性集合或迭代器会更节省内存。次要
缓存
ID 前缀检测内容检测方法严重程度
PERF同一请求中重复执行相同查询在单个请求/函数调用中多次执行相同的查询模式,且没有缓存结果。次要
PERF缓存未设置 TTLCache::put()、cache.set()、没有过期时间的 Redis SET。永久缓存的数据可能会过时。次要
PERF写入后未使缓存失效创建/更新/删除操作未清除或更新相关缓存条目。数据变更后仍提供过时的缓存。重大
算法效率
ID 前缀检测内容检测方法严重程度
PERF热点路径中的 O(n^2) 或更差复杂度嵌套循环遍历相同或相关的集合。在循环中使用 array_search/in_array/includes()(在循环中线性搜索即为 O(n^2))。重大
PERF在循环中排序在循环体内调用 sort()、usort()、array_sort()、.sort()。重大
PERF可用哈希映射替代的线性搜索在同一数组上重复使用 in_array()、.includes()、.indexOf()、list.index(),而预先构建 Set/字典/哈希映射后,每次查找即可达到 O(1)。次要
并发
ID 前缀检测内容检测方法严重程度
PERF读-改-写中的竞态条件在没有锁的情况下读取值、修改值并写回的模式:在并发环境中递增计数器、更新余额、切换标志。严重
PERF队列任务缺少幂等性未检查重复执行的队列/任务处理程序。创建资源时未检查资源是否已存在的任务。任务创建的数据缺少唯一约束。重大
PERF异步上下文中的共享可变状态异步处理程序访问全局/模块级可变变量,或将请求范围的数据存储在模块作用域中。重大
前端性能
ID 前缀检测内容检测方式严重程度
PERF不必要的重复渲染对昂贵的计算,或每次渲染都会收到新对象/数组引用的组件,缺少 React.memo、useMemo、useCallback。在 JSX 属性中内联创建对象/数组。轻微
PERF导入了体积较大的依赖包import _ from 'lodash'(导入整个库)、import moment from 'moment'(体积较大的库,而 date-fns 或 dayjs 已足够)、import * as icons from 'icon-library'。轻微
PERF缺少延迟加载没有使用 React.lazy() / 动态 import() 按路由拆分代码。较重的组件在初始页面加载时就被 eager 加载。轻微
可选脚本集成

当 scripts/complexity_scorer.py 的输出可用时(由编排器在 /codeprobe audit 期间运行),使用它来识别复杂度较高的函数,并将其作为潜在性能热点候选。评级为 "high" 或 "very_high",且出现在热点路径(请求处理程序、循环体、频繁调用的实用工具函数)中的函数,是发现算法效率问题的强烈信号。


ID 前缀和修复提示词示例

所有发现均使用 PERF- 前缀,并按顺序编号:PERF-001、PERF-002 等。

修复提示词示例
  • "在 OrderController@index(第 22 行)中,为 Order::query() 调用添加 ->with('items', 'customer'),以修复 N+1 问题——当前在 orders/index.blade.php:15 的 Blade 循环中延迟加载 2 个关联。"
  • "将 CatalogService.php 第 30 行的 Product::all() 替换为 Product::query()->paginate(25),或者在处理所有记录时使用 Product::cursor()。当前查询会将所有产品加载到内存中。"
  • "在 ReportGenerator@aggregate(第 45–60 行)中,遍历 $customers 内部的 $orders 的嵌套循环复杂度为 O(n*m)。在外层循环之前构建查找哈希映射:$ordersByCustomerId = collect($orders)->groupBy('customer_id')。"
  • "将 src/utils/helpers.ts 第 3 行的 import _ from 'lodash' 替换为特定导入:import debounce from 'lodash/debounce',以减小打包体积。"

评论

支持 Markdown