| name | performance-profiling |
| description | CPU, memory, network bottleneck analysis โ systematic performance investigation |
| tier | standard |
| applyTo | **/*profile*,**/*performance*,**/*benchmark*,**/*bottleneck*,**/*optimize* |
Performance Profiling Skill
Find the bottleneck before optimizing. Measure twice, optimize once.
The Golden Rule
"Premature optimization is the root of all evil" โ Donald Knuth
But also:
"Measure, don't guess" โ Everyone who's optimized the wrong thing
Performance Investigation Flow
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. OBSERVE โ
โ User reports slowness โ Reproduce โ Measure baseline โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 2. IDENTIFY โ
โ Profile โ Find hotspots โ Determine bottleneck type โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 3. HYPOTHESIZE โ
โ Why is this slow? โ Form theory โ Plan fix โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 4. OPTIMIZE โ
โ Implement fix โ Measure improvement โ Verify โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโค
โ 5. MONITOR โ
โ Add metrics โ Set alerts โ Prevent regression โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Bottleneck Types
| Type | Symptoms | Investigation |
|---|
| CPU-bound | High CPU, reasonable memory | Profile CPU, look for hot functions |
| Memory-bound | High memory, GC pauses | Heap profile, allocation tracking |
| I/O-bound | Low CPU, waiting on disk/network | Trace I/O operations, latency |
| Concurrency | Low utilization, contention | Thread dumps, lock analysis |
| Network | High latency to external services | Trace calls, measure RTT |
| Database | Slow queries, connection wait | Query plans, pool stats |
CPU Profiling
Node.js
node --prof app.js
node --prof-process isolate-*.log > processed.txt
node --inspect app.js
npm install -g clinic
clinic doctor -- node app.js
clinic flame -- node app.js
Reading Flame Graphs
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ main() โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ โ processData() โ โ renderUI() โโ
โ โ โโโโโโโโโโโโ โโโโโโโโ โ โ โโโโโโโโ โโโโโโโโโโ โโ
โ โ โ parseJSONโโ โsort()โ โ โ โlayoutโโ โ paint()โ โโ
โ โ โโโโโโโโโโโโ โโโโโโโโ โ โ โโโโโโโโ โโโโโโโโโโ โโ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Width = Time spent
- Wide bars = slow functions (targets for optimization)
- Deep stacks = look for unnecessary recursion
- Flat tops = time spent in that function, not children
.NET
dotnet trace collect --process-id <PID> --format speedscope
dotnet counters monitor --process-id <PID>
Memory Profiling
Node.js Heap Analysis
const v8 = require('v8');
const fs = require('fs');
const snapshotPath = `heap-${Date.now()}.heapsnapshot`;
const snapshot = v8.writeHeapSnapshot(snapshotPath);
console.log(`Heap snapshot written to ${snapshot}`);
console.log(process.memoryUsage());
Common Memory Leaks
| Pattern | Cause | Fix |
|---|
| Uncleared intervals | setInterval without cleanup | Store and clear in teardown |
| Event listener accumulation | Adding listeners without removing | Remove in cleanup |
| Closure capture | Large objects in closures | Null out references |
| Growing collections | Maps/Sets that never shrink | Implement eviction |
| Global state | Module-level caches | Add size limits, TTL |
.NET Memory
dotnet-dump collect -p <PID>
dotnet-dump analyze <dump-file>
dotnet-counters monitor --counters System.Runtime
Network Profiling
Browser DevTools
- Network tab โ Record
- Look for:
- Waterfall โ Blocked/waiting time
- Size โ Large payloads
- Time โ Slow responses
API Latency Breakdown
Total Request Time: 500ms
โโโ DNS Lookup: 20ms
โโโ TCP Connection: 30ms
โโโ TLS Handshake: 50ms (HTTPS)
โโโ Time to First Byte: 350ms โ Server processing
โโโ Content Download: 50ms
Common Network Issues
| Issue | Symptom | Fix |
|---|
| No keep-alive | TCP handshake per request | Enable connection reuse |
| Large payloads | Slow transfer | Compress, paginate |
| No caching | Repeat downloads | Cache headers |
| Waterfall blocking | Sequential requests | Parallelize, HTTP/2 |
| DNS latency | First request slow | DNS prefetch |
Database Profiling
Query Analysis
ALTER SYSTEM SET log_min_duration_statement = 100;
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 0.1;
Query Plan Analysis
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT * FROM orders WHERE customer_id = 123;
Connection Pool Issues
| Symptom | Cause | Fix |
|---|
| Waiting for connection | Pool exhausted | Increase pool size |
| Many idle connections | Pool too large | Decrease max connections |
| Connection timeout | Queries holding connections | Add query timeout |
VS Code Extension Profiling
For Alex-like extensions:
Activation Performance
export async function activate(context: vscode.ExtensionContext) {
const start = performance.now();
console.log(`Extension activated in ${performance.now() - start}ms`);
telemetry.logUsage('activation', { durationMs: performance.now() - start });
}
Command Performance
function withTiming<T>(
commandId: string,
handler: () => Promise<T>
): () => Promise<T> {
return async () => {
const start = performance.now();
try {
return await handler();
} finally {
const duration = performance.now() - start;
if (duration > 1000) {
console.warn(`Slow command: ${commandId} took ${duration}ms`);
}
}
};
}
Extension Host Profiling
- Developer: Show Running Extensions
- Note CPU/memory per extension
- Use
--prof flag for detailed profiling
Benchmarking Best Practices
Benchmark Setup
import Benchmark from 'benchmark';
const suite = new Benchmark.Suite();
suite
.add('Method A', () => methodA(testData))
.add('Method B', () => methodB(testData))
.on('cycle', (event) => console.log(String(event.target)))
.on('complete', function() {
console.log('Fastest is ' + this.filter('fastest').map('name'));
})
.run({ async: true });
Benchmarking Rules
- Warm up โ Run once before measuring
- Isolate โ One variable at a time
- Repeat โ Statistical significance (n > 30)
- Realistic data โ Use production-like inputs
- Disable optimizations โ Ensure code runs (avoid dead code elimination)
- Document baseline โ Record environment, date, conditions
Performance Optimization Patterns
Caching
| Level | Latency | Example |
|---|
| L1 Cache | 1ns | CPU cache |
| L2 Cache | 4ns | CPU cache |
| RAM | 100ns | In-memory cache |
| SSD | 100ฮผs | Local database |
| Network | 1-100ms | Remote API |
Cache strategy:
async function getCached<T>(key: string, fetchFn: () => Promise<T>, ttlMs: number): Promise<T> {
const cached = cache.get(key);
if (cached && cached.expires > Date.now()) {
return cached.value;
}
const value = await fetchFn();
cache.set(key, { value, expires: Date.now() + ttlMs });
return value;
}
Lazy Evaluation
const allUsers = users.filter(u => u.active).map(u => u.name);
const firstTen = allUsers.slice(0, 10);
function* activeUserNames(users) {
for (const user of users) {
if (user.active) yield user.name;
}
}
const iterator = activeUserNames(users);
const firstTen = Array.from({ length: 10 }, () => iterator.next().value);
Batching
for (const id of ids) {
await fetchUser(id);
}
const users = await fetchUsers(ids);
Debouncing/Throttling
function debounce(fn: Function, delay: number) {
let timeout: NodeJS.Timeout;
return (...args: any[]) => {
clearTimeout(timeout);
timeout = setTimeout(() => fn(...args), delay);
};
}
function throttle(fn: Function, interval: number) {
let lastCall = 0;
return (...args: any[]) => {
const now = Date.now();
if (now - lastCall >= interval) {
lastCall = now;
fn(...args);
}
};
}
Performance Budget
Define acceptable limits:
| Metric | Budget | Measurement |
|---|
| Page load (LCP) | < 2.5s | Lighthouse |
| API response (P95) | < 500ms | APM |
| Memory (steady state) | < 100MB | Heap snapshot |
| Bundle size | < 200KB gzip | Build output |
| Startup time | < 100ms | Activation timing |
Implementation Checklist
Investigation
Optimization
Prevention
Related Skills
- observability-monitoring โ Ongoing performance visibility
- database-design โ Query optimization at design level
- debugging-patterns โ Systematic investigation approaches
- code-review โ Catch performance issues in review
The fastest code is code that doesn't run. The second fastest is code that runs once.