用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/Sumatoshi-tech/codefang --skill perf命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Systematic bug diagnosis and test-driven fix workflow
Audit and improve open-source documentation against best-practice rubrics (Diátaxis, Good Docs Project, Standard README, Google/Microsoft style, Keep a Changelog, MADR, OpenSSF)
Feature requirements document template
基于 SOC 职业分类
正在显示 SKILL.md
| name | perf |
| description | Performance diagnosis and optimization workflow |
You must first diagnose the bottleneck (waiting vs compute vs lock contention vs boundary overhead), then implement the architecture that matches the findings, because optimizing without a diagnosis often makes performance worse by solving the wrong problem.
Create a deterministic benchmark run:
Record:
Acceptance: results reproducible within +/-5-10%.
Capture a 10-30s runtime/trace under load and inspect with go tool trace.
What to look for:
chan send/recv) or mutexes (sync.Mutex, RWMutex).Interpretation rules:
Collect:
pprof CPU)-blockprofile)-mutexprofile)Red flags:
runtime.mallocgc, scanobject, gcAssistAlloc = allocation/GC pressurechansend / chanrecv = channel contentionsync.(*Mutex).Lock / RWMutex = lock contentionInterpretation rules:
On Linux, run perf top or perf record against the process during steady-state.
What to look for:
futex, pthread_mutex_*, __lll_lock_wait: lock contentionpage_fault, do_page_fault, mmap, read, pread: memory pressure / I/O boundmemcpy / copy_user: excessive copying between layersOn macOS, use Instruments.app or dtrace for system-level profiling:
instruments -t "Time Profiler" -p <pid> for CPU samplingsudo dtrace -n 'profile-997 /pid == $target/ { @[ustack()] = count(); }' for stack samplingsudo fs_usage -w -f filesys <pid> for filesystem activitysample <pid> 10 -file output.txt for quick stack sampling without InstrumentsWhat to look for:
mach_msg_trap: thread communication overheadkevent/kqueue: event loop bottleneckvm_fault spikes: memory pressure / page cache churnpthread_mutex_* or os_unfair_lock: lock contentionCapture at least one of:
iostat -x 1 / pidstat -d 1 (disk await/util)pidstat -w 1 (context switches)vmstat 1 (runnable queue, iowait)perf stat (cycles, stalled-cycles, context-switches, page-faults)iostat -w 1 (disk throughput)vm_stat 1 (page faults, swap, free/active/inactive pages)fs_usage -w <pid> (per-process filesystem activity)top -l 1 -stats pid,cpu,mem,csw (context switches per process)Interpretation rules (both platforms):
After 1.2-1.5, classify into ONE primary bottleneck:
Class A -- Boundary overhead
Class B -- Go orchestration contention
Class C -- External library / system contention
Class D -- I/O / page fault bound
Class E -- GC/allocation bound
Write a short diagnosis note mapping evidence to class.
sync.Pool for frequently allocated objects.arena package for batch allocations (Go 1.20+, experimental).// Use sync.Pool for frequently allocated objects
var bufPool = sync.Pool{
New: func() any { return new(bytes.Buffer) },
}
// Pre-allocate slices when size is known
results := make([]Result, 0, expectedCount)
// Use strings.Builder for string concatenation
var sb strings.Builder
sb.Grow(estimatedSize)
// Sharded worker pattern - avoid single channel bottleneck
type ShardedQueue struct {
shards []chan Task
}
func (q *ShardedQueue) Submit(task Task) {
shard := task.ID % uint32(len(q.shards))
q.shards[shard] <- task
}
// Per-worker results, merge at end
results := make([][]Result, numWorkers)
// ... each worker writes to results[workerID]
// ... merge after all workers done
// Use buffered I/O
writer := bufio.NewWriterSize(file, 64*1024)
defer writer.Flush()
// Use io.Copy instead of reading entire files into memory
io.Copy(dst, src)
// Batch cgo calls - one call does a lot of work
// BAD: one cgo call per item
for _, item := range items {
C.process_item(item)
}
// GOOD: one cgo call for entire batch
C.process_batch((*C.Item)(unsafe.Pointer(&items[0])), C.int(len(items)))
// Use C-allocated memory for large data passed to C
ptr := C.malloc(C.size_t(size))
defer C.free(ptr)
strconv or strings.Builder in hot paths instead of fmt.Sprintf, because formatting is expensive.You must output:
If diagnosis is missing, the design is considered incomplete.
<self_check>
Before proposing any optimization, verify:
</self_check>