perf-review

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Performance Review

性能审查

Review code changes for performance problems and report them. Do not change code. The user decides what to fix.
审查代码变更中的性能问题并进行报告。请勿修改代码,由用户决定需要修复的内容。

Step 1: Pick the scope

步骤1:选择审查范围

Ask git what changed. Pick the first case that matches the request:
RequestCommand
"my changes", "uncommitted"
git diff HEAD
(staged + unstaged)
"last commit", a commit hash
git diff <hash>^ <hash>
a branch or PR
git diff $(git merge-base main HEAD)...HEAD
a GitHub PR number or URL
gh pr diff <number>
"this file", "this package"Read the named files directly
If the request is ambiguous and there are uncommitted changes, review those. Say what scope you chose.
通过git命令查看变更内容。根据用户请求选择第一个匹配的情况:
请求内容命令
"my changes"、"uncommitted"
git diff HEAD
(已暂存+未暂存内容)
"last commit"、提交哈希值
git diff <hash>^ <hash>
分支或PR
git diff $(git merge-base main HEAD)...HEAD
GitHub PR编号或URL
gh pr diff <number>
"this file"、"this package"直接读取指定文件
如果请求模糊且存在未提交变更,则审查这些未提交内容,并说明你选择的审查范围。

Step 2: Read beyond the diff

步骤2:查看diff之外的上下文

A diff hides the context that decides whether code is slow. Before you judge a hunk, read the full function it lives in, and find its callers:
  • A loop around the call site changes everything. One allocation is free. The same allocation inside a loop over a million rows is a GC storm. Grep for callers of each changed function to learn how hot it is.
  • Hot path or cold path? Request handlers, render functions, loops over datasets, and anything called per row or per frame are hot. Init code, CLI argument parsing, and error paths that fire once are cold. Only flag cold-path code when the problem is algorithmic (a real O(n²) grows into the hot path on its own).
  • Data size matters.
    array.includes
    in a loop over 20 items is fine. Over 20,000 it is a quadratic bug. When the size is not visible in the code, say what size makes the finding real.
diff会隐藏判断代码是否缓慢的上下文信息。在判断代码块之前,请先阅读其所在的完整函数,并找到调用该函数的位置:
  • 调用位置的循环会改变一切。单次内存分配几乎没有影响,但在百万行数据的循环中进行相同的分配会引发GC风暴。通过grep查找每个变更函数的调用方,了解其调用频率。
  • 热路径还是冷路径? 请求处理器、渲染函数、数据集循环以及每行/每帧都会调用的代码属于热路径。初始化代码、CLI参数解析和仅触发一次的错误路径属于冷路径。仅当冷路径代码存在算法问题(如真实的O(n²)算法会随数据增长进入热路径)时才标记。
  • 数据规模很重要。在20条数据的循环中使用
    array.includes
    没有问题,但在20000条数据中使用则会导致二次复杂度问题。当代码中无法看到数据规模时,请说明何种规模会使问题显现。

Step 3: Apply the language checklist

步骤3:应用语言检查清单

Read the reference for each language present in the diff, and check every changed hunk against its list:
  • Go files → read
    references/go.md
  • TypeScript / JavaScript / TSX files → read
    references/typescript.md
阅读diff中涉及的每种语言的参考文档,并对照清单检查每个变更的代码块:
  • Go文件 → 阅读
    references/go.md
  • TypeScript/JavaScript/TSX文件 → 阅读
    references/typescript.md

Step 4: Report

步骤4:生成报告

Use this exact structure:
markdown
undefined
使用以下固定结构:
markdown
undefined

Performance review: <scope>

Performance review: <scope>

Findings

Findings

1. <short title>
path/file.go:123

1. <short title>
path/file.go:123

Severity: high | medium | low Pattern: <name from the reference, e.g. "append without preallocation"> Why it is slow: <one or two sentences, tied to this code's actual call pattern and data size> Fix: <minimal code snippet of the fix — not applied, just shown>
Severity: high | medium | low Pattern: <参考文档中的名称,例如"append without preallocation"> Why it is slow: <一到两句话,结合代码实际调用模式和数据规模说明原因> Fix: <修复的最小代码片段——仅展示,不直接应用>

Not flagged

Not flagged

<one line per pattern you saw but deliberately left alone, with the reason — e.g. "string concat in cmd/init.go: runs once at startup">
<每行记录一个你看到但刻意忽略的模式及原因——例如"string concat in cmd/init.go: runs once at startup">

Verify

Verify

<the one or two commands that would confirm the top findings — see below>

Severity rules:

- **high** — hot path, measurable at current scale: quadratic algorithm over real data, N+1 query, per-request allocation storm, blocked event loop, unbounded goroutines or promises.
- **medium** — hot path but small constant factor, or a cold-path algorithmic problem that grows with data.
- **low** — real but minor; mention only when the fix is one line.

Cite line numbers from `grep -n` output, diff hunk headers, or a numbered read — never from memory. One wrong line number costs the whole review its credibility.

Order findings by severity. If there are no findings, say so plainly — no low-severity filler to look thorough.
<用于确认主要问题的一到两个命令——见下文>

严重程度规则:

- **high(高)** — 热路径,当前规模下可测量:真实数据上的二次复杂度算法、N+1查询、每次请求的内存分配风暴、阻塞事件循环、无界goroutine或promise。
- **medium(中)** — 热路径但常数因子小,或随数据增长的冷路径算法问题。
- **low(低)** — 真实存在但影响轻微;仅当修复只需一行代码时提及。

引用行号来自`grep -n`输出、diff块头或带编号的读取结果——切勿凭记忆填写。错误的行号会使整个审查失去可信度。

按严重程度排序问题。如果没有问题,请直接说明——不要为了显得全面而添加低严重程度的无关内容。

Step 5: Point at verification, not guesses

步骤5:提供验证方法,而非猜测

Every high finding gets a way to confirm it — take the command from the Verification section of the language reference. Do not run benchmarks yourself unless asked; give the command.
If you are not sure a finding is real, keep it, mark the severity honestly, and say what measurement decides it. A review that only reports certainties misses the expensive bugs; a review that states guesses as facts wastes the reader's day. Label which is which.
每个高严重程度的问题都需要提供验证方法——从语言参考文档的Verification部分获取命令。除非被要求,否则不要自行运行基准测试;只需提供命令即可。
如果你不确定某个问题是否真实存在,请保留该问题,如实标记严重程度,并说明需要通过何种测量来确认。只报告确定性问题的审查会遗漏代价高昂的bug;将猜测当作事实的审查会浪费读者的时间。请明确区分两者。