performance

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

RTK Performance Analysis

RTK 性能分析

Hard Targets (Non-Negotiable)

硬性指标(不可妥协)

MetricTargetBlocker
Startup time<10msRelease blocker
Binary size (stripped)<5MBRelease blocker
Memory (resident)<5MBRelease blocker
Token savings per filter≥60%Release blocker
指标目标发布阻塞条件
启动时间<10ms阻塞发布
二进制文件大小(裁剪后)<5MB阻塞发布
驻留内存<5MB阻塞发布
单次过滤Token节省率≥60%阻塞发布

Benchmark Startup Time

启动时间基准测试

bash
undefined
bash
undefined

Install hyperfine (once)

安装 hyperfine(仅需一次)

brew install hyperfine
brew install hyperfine

Baseline (before changes)

基准值(变更前)

hyperfine 'rtk git status' --warmup 3 --export-json /tmp/before.json
hyperfine 'rtk git status' --warmup 3 --export-json /tmp/before.json

After changes — rebuild first

变更后 —— 先重新构建

cargo build --release
cargo build --release

Compare against installed

和已安装版本对比

hyperfine 'target/release/rtk git status' 'rtk git status' --warmup 3
hyperfine 'target/release/rtk git status' 'rtk git status' --warmup 3

Target: <10ms mean time

目标:平均耗时 <10ms

undefined
undefined

Check Binary Size

检查二进制文件大小

bash
undefined
bash
undefined

Release build with strip=true (already in Cargo.toml)

开启 strip=true 的Release构建(已在Cargo.toml中配置)

cargo build --release ls -lh target/release/rtk
cargo build --release ls -lh target/release/rtk

Should be <5MB

应该 <5MB

If too large — check what's contributing

如果体积过大 —— 检查占用来源

cargo bloat --release --crates cargo bloat --release -n 20
cargo bloat --release --crates cargo bloat --release -n 20

Install: cargo install cargo-bloat

安装方式:cargo install cargo-bloat

undefined
undefined

Memory Usage

内存占用

bash
undefined
bash
undefined

macOS

macOS

/usr/bin/time -l target/release/rtk git status 2>&1 | grep "maximum resident"
/usr/bin/time -l target/release/rtk git status 2>&1 | grep "maximum resident"

Target: <5,000,000 bytes (5MB)

目标:<5,000,000 字节 (5MB)

Linux

Linux

/usr/bin/time -v target/release/rtk git status 2>&1 | grep "Maximum resident"
/usr/bin/time -v target/release/rtk git status 2>&1 | grep "Maximum resident"

Target: <5,000 kbytes

目标:<5,000 千字节

undefined
undefined

Regex Compilation Audit

正则编译审计

Regex compilation on every function call is a common perf killer:
bash
undefined
每次函数调用时编译正则是常见的性能杀手:
bash
undefined

Find all Regex::new calls

查找所有 Regex::new 调用

grep -n "Regex::new" src/*.rs
grep -n "Regex::new" src/*.rs

Verify ALL are inside lazy_static! blocks

确认所有调用都在 lazy_static! 块内

Any Regex::new outside lazy_static! = performance bug

任何位于 lazy_static! 外的 Regex::new 都属于性能Bug


```rust
// ❌ Recompiles on every filter_line() call
fn filter_line(line: &str) -> bool {
    let re = Regex::new(r"^error").unwrap();  // BAD
    re.is_match(line)
}

// ✅ Compiled once at first use
lazy_static! {
    static ref ERROR_RE: Regex = Regex::new(r"^error").unwrap();
}
fn filter_line(line: &str) -> bool {
    ERROR_RE.is_match(line)  // GOOD
}

```rust
// ❌ 每次调用filter_line()都会重新编译
fn filter_line(line: &str) -> bool {
    let re = Regex::new(r"^error").unwrap();  // 错误写法
    re.is_match(line)
}

// ✅ 首次使用时仅编译一次
lazy_static! {
    static ref ERROR_RE: Regex = Regex::new(r"^error").unwrap();
}
fn filter_line(line: &str) -> bool {
    ERROR_RE.is_match(line)  // 正确写法
}

Dependency Impact Assessment

依赖影响评估

Before adding any new crate:
bash
undefined
添加任何新crate之前:
bash
undefined

Check startup impact (measure before adding)

检查对启动速度的影响(添加依赖前先测量)

hyperfine 'rtk git status' --warmup 3
hyperfine 'rtk git status' --warmup 3

Add dependency to Cargo.toml

在Cargo.toml中添加依赖

Rebuild

重新构建

cargo build --release
cargo build --release

Measure after

添加后测量

hyperfine 'target/release/rtk git status' --warmup 3
hyperfine 'target/release/rtk git status' --warmup 3

If startup increased >1ms — investigate

如果启动耗时增加>1ms —— 排查原因

If startup increased >3ms — reject the dependency

如果启动耗时增加>3ms —— 拒绝引入该依赖

undefined
undefined

Forbidden dependencies

禁用的依赖

CrateReasonAlternative
tokio
+5-10ms startupBlocking
std::process::Command
async-std
+5-10ms startupBlocking I/O
rayon
Thread pool init overheadSequential iteration
reqwest
Pulls tokio
ureq
(blocking) if HTTP needed
Crate原因替代方案
tokio
增加5-10ms启动耗时阻塞式
std::process::Command
async-std
增加5-10ms启动耗时阻塞式I/O
rayon
线程池初始化开销顺序迭代
reqwest
会引入tokio依赖如需HTTP功能使用
ureq
(阻塞式)

Dependency weight check

依赖权重检查

bash
undefined
bash
undefined

After cargo build --release

执行cargo build --release之后

cargo build --release --timings
cargo build --release --timings

Open target/cargo-timings/cargo-timing.html

打开 target/cargo-timings/cargo-timing.html

Look for crates with long compile times (correlates with complexity)

查找编译时间长的crate(和复杂度正相关)

undefined
undefined

Allocation Profiling

内存分配分析

bash
undefined
bash
undefined

macOS — use Instruments

macOS —— 使用Instruments

instruments -t Allocations target/release/rtk git log -10
instruments -t Allocations target/release/rtk git log -10

Or use cargo-instruments

或者使用cargo-instruments

cargo install cargo-instruments cargo instruments --release -t Allocations -- git log -10

Common RTK allocation hotspots:

```rust
// ❌ Allocates new String on every line
let lines: Vec<String> = input.lines().map(|l| l.to_string()).collect();

// ✅ Borrow slices
let lines: Vec<&str> = input.lines().collect();

// ❌ Clone large output unnecessarily
let raw_copy = output.stdout.clone();

// ✅ Use reference until you actually need to own
let display = &output.stdout;
cargo install cargo-instruments cargo instruments --release -t Allocations -- git log -10

RTK常见内存分配热点:

```rust
// ❌ 每一行都分配新的String
let lines: Vec<String> = input.lines().map(|l| l.to_string()).collect();

// ✅ 借用切片
let lines: Vec<&str> = input.lines().collect();

// ❌ 不必要地克隆大型输出
let raw_copy = output.stdout.clone();

// ✅ 在真正需要所有权之前使用引用
let display = &output.stdout;

Token Savings Measurement

Token节省率测算

rust
// In tests — always verify claims
fn count_tokens(text: &str) -> usize {
    text.split_whitespace().count()
}

#[test]
fn test_savings_claim() {
    let input = include_str!("../tests/fixtures/mycmd_raw.txt");
    let output = filter_output(input).unwrap();

    let input_tokens = count_tokens(input);
    let output_tokens = count_tokens(&output);
    let savings = 100.0 * (1.0 - output_tokens as f64 / input_tokens as f64);

    assert!(
        savings >= 60.0,
        "Expected ≥60% savings, got {:.1}% ({} → {} tokens)",
        savings, input_tokens, output_tokens
    );
}
rust
// 在测试中始终验证指标达标情况
fn count_tokens(text: &str) -> usize {
    text.split_whitespace().count()
}

#[test]
fn test_savings_claim() {
    let input = include_str!("../tests/fixtures/mycmd_raw.txt");
    let output = filter_output(input).unwrap();

    let input_tokens = count_tokens(input);
    let output_tokens = count_tokens(&output);
    let savings = 100.0 * (1.0 - output_tokens as f64 / input_tokens as f64);

    assert!(
        savings >= 60.0,
        "预期节省≥60%,实际为{:.1}% ({} → {} 个Token)",
        savings, input_tokens, output_tokens
    );
}

Before/After Regression Check

变更前后回归检查

Template for any performance-sensitive change:
bash
undefined
所有性能敏感变更的检查模板:
bash
undefined

1. Baseline

1. 基准测试

cargo build --release hyperfine 'target/release/rtk git status' --warmup 5 --export-json /tmp/before.json /usr/bin/time -l target/release/rtk git status 2>&1 | grep "maximum resident" ls -lh target/release/rtk
cargo build --release hyperfine 'target/release/rtk git status' --warmup 5 --export-json /tmp/before.json /usr/bin/time -l target/release/rtk git status 2>&1 | grep "maximum resident" ls -lh target/release/rtk

2. Make changes

2. 执行变更

... edit code ...

... 编辑代码 ...

3. Rebuild and compare

3. 重新构建并对比

cargo build --release hyperfine 'target/release/rtk git status' --warmup 5 --export-json /tmp/after.json /usr/bin/time -l target/release/rtk git status 2>&1 | grep "maximum resident" ls -lh target/release/rtk
cargo build --release hyperfine 'target/release/rtk git status' --warmup 5 --export-json /tmp/after.json /usr/bin/time -l target/release/rtk git status 2>&1 | grep "maximum resident" ls -lh target/release/rtk

4. Compare

4. 对比结果

Startup: jq '.results[0].mean' /tmp/before.json /tmp/after.json

启动时间对比:jq '.results[0].mean' /tmp/before.json /tmp/after.json

If after > before + 1ms: investigate

如果变更后数值 > 变更前+1ms:排查问题

If after > 10ms: regression, do not merge

如果变更后数值 > 10ms:存在性能回归,禁止合并

undefined
undefined