Code Analysis
Overview
Section titled “Overview”modestbench’s code analysis feature (via the analyze command, alias profile) helps you identify which functions in your codebase consume the most execution time. This is invaluable for:
- Finding benchmark candidates: Discover which functions would benefit most from optimization
- Guided performance work: Focus your efforts on code that matters
- Understanding bottlenecks: See where your application spends time during execution
The analyzer uses Node.js’s built-in V8 profiler (--cpu-prof) to capture real execution data, then filters and presents the results.
Quick Start
Section titled “Quick Start”Analyze any Node.js command to see hot code paths:
# Try the profiling demo (shows clear hot paths)modestbench analyze "node examples/profiling-demo.js"
# Analyze your test suitemodestbench analyze "npm test"
# Analyze a specific scriptmodestbench analyze "node ./src/server.js"
# Analyze your application startupmodestbench analyze "node ./dist/index.js"Profile Storage
Section titled “Profile Storage”CPU profiles are stored in .modestbench/profiles/ to keep your workspace clean. This directory is automatically gitignored.
You can analyze existing profiles with the --input flag:
modestbench analyze --input .modestbench/profiles/CPU.bunchanumbers.cpuprofileUnderstanding the Output
Section titled “Understanding the Output”The profiler shows functions that consume the most CPU time:
██ Profile Analysis
Command: npm testDuration: 5.2sTotal Ticks: 8,234
██ Benchmark Candidates
Top functions by execution time:
sortArray 12.3% (1,013 ticks) src/utils/sorting.js:42
validateSchema 8.7% (716 ticks) src/validators/schema.js:28
parseInput 6.1% (502 ticks) src/parsers/input.js:15
... (showing top 3 of 45 user functions)What the Colors Mean
Section titled “What the Colors Mean”Functions are color-coded by execution percentage:
- Red (≥10%): Critical hot paths - highest priority for benchmarking
- Yellow (≥5%): Significant execution time - good candidates
- Cyan (≥2%): Moderate impact - consider for optimization
- White (<2%): Minor impact - usually not worth benchmarking
Ticks Explained
Section titled “Ticks Explained”A “tick” is a CPU time sample. The V8 profiler periodically samples what function is executing. More ticks = more time spent in that function. The percentage shows what portion of total execution time each function consumed.
Smart Detection
Section titled “Smart Detection”By default, the profiler uses smart detection to focus on your code:
- ✅ Includes: Functions from your project directory
- ❌ Excludes:
node_modulesdependencies - ❌ Excludes: Node.js internals (
node:*,internal/*)
This filtering helps you focus on code you can actually optimize, rather than third-party libraries.
Filtering Options
Section titled “Filtering Options”Override smart detection with explicit patterns:
# Focus on specific filesmodestbench analyze "npm test" --filter-file "**/utils/**"
# Set minimum threshold (default: 1%)modestbench analyze "npm test" --min-percent 5.0
# Show more results (default: 25)modestbench analyze "npm test" --top 50Grouped View
Section titled “Grouped View”Use --group-by-file to see results organized by source file:
modestbench analyze "npm test" --group-by-fileOutput:
██ Grouped by File
▓ src/utils/sorting.js 18.5% (1,523 ticks) ▪ sortArray 12.3% (1,013 ticks) :42 ▪ quickSort 4.2% (346 ticks) :98 ▪ partition 2.0% (164 ticks) :125
▓ src/validators/schema.js 11.3% (931 ticks) ▪ validateSchema 8.7% (716 ticks) :28 ▪ checkRequired 2.6% (215 ticks) :145This view is particularly useful for:
- Identifying files with multiple hot functions
- Understanding the overall performance impact of a module
- Prioritizing which files to focus optimization efforts on
Analyzing Existing Profiles
Section titled “Analyzing Existing Profiles”If you already have V8 profile logs, you can analyze them directly:
# Analyze an existing profilemodestbench analyze --input isolate-0x123-v8.logThis is useful for:
- Analyzing profiles from production environments
- Comparing profiles from different runs
- Processing profiles generated with custom
NODE_OPTIONS
Workflow: From Profile to Benchmark
Section titled “Workflow: From Profile to Benchmark”Here’s a recommended workflow for using profiling data:
1. Profile Your Code
Section titled “1. Profile Your Code”Start by profiling a representative workload:
# Profile your test suite (good for library development)modestbench analyze "npm test"
# Or profile your application with typical usagemodestbench analyze "node ./dist/app.js --run-typical-task"2. Identify Candidates
Section titled “2. Identify Candidates”Look for functions that meet these criteria:
- High execution percentage (≥5%)
- Pure/deterministic: Same inputs → same outputs
- Frequently called: Optimization will have broad impact
- In your codebase: You can actually change them
3. Create Benchmarks
Section titled “3. Create Benchmarks”First, initialize the benchmarking system if you haven’t already:
modestbench initNow, for each candidate, create a focused benchmark:
import { sortArray } from '../src/utils/sorting.js';
const small = Array.from({ length: 100 }, () => Math.random());const medium = Array.from({ length: 1000 }, () => Math.random());const large = Array.from({ length: 10000 }, () => Math.random());
export default { suites: { 'Array Sorting': { benchmarks: { 'sortArray - small (100)': () => sortArray([...small]), 'sortArray - medium (1000)': () => sortArray([...medium]), 'sortArray - large (10000)': () => sortArray([...large]), }, }, },};4. Run and Track
Section titled “4. Run and Track”Run your benchmarks to establish a baseline:
modestbench
# Track over timemodestbench history trendsCommon Use Cases
Section titled “Common Use Cases”Profiling Tests
Section titled “Profiling Tests”Find hot paths in your test suite:
modestbench analyze "npm test"Why this is useful:
- Tests often exercise core functionality
- High test execution time often indicates real performance issues
- Easy to reproduce and measure
Profiling Application Startup
Section titled “Profiling Application Startup”Identify slow initialization code:
modestbench analyze "node ./dist/app.js" --group-by-fileLook for:
- Heavy parsing/validation on startup
- Expensive module initialization
- Synchronous I/O during startup
Profiling Specific Scenarios
Section titled “Profiling Specific Scenarios”Target specific operations:
# Profile data processingmodestbench analyze "node scripts/process-data.js"
# Profile API requestsmodestbench analyze "node scripts/load-test.js"Command Reference
Section titled “Command Reference”modestbench analyze [command]
Options: --input, -i Path to existing *.cpuprofile file --filter-file Filter functions by file glob pattern --min-percent Minimum execution percentage (default: 0.5) --top, -n Number of top functions to show (default: 25) --group-by-file Group results by source file --color Enable/disable colored outputTips and Best Practices
Section titled “Tips and Best Practices”Run Multiple Times
Section titled “Run Multiple Times”V8 profiling has some variability. Run 2-3 times to verify consistent results:
modestbench analyze "npm test"# Run againmodestbench analyze "npm test"Functions consistently appearing at the top are your best candidates.
Use Representative Workloads
Section titled “Use Representative Workloads”Profile code that exercises realistic scenarios:
# ❌ Not representativemodestbench analyze "node --eval 'console.log(1)'"
# ✅ Representative workloadmodestbench analyze "npm test"modestbench analyze "node ./scripts/typical-task.js"Combine with Benchmarking
Section titled “Combine with Benchmarking”Use profiling to discover candidates, benchmarking to measure improvements:
# 1. Profile to find hot pathsmodestbench analyze "npm test" > profile-baseline.txt
# 2. Create benchmarks for hot functions# ... create benchmarks ...
# 3. Run benchmarks to establish baselinemodestbench
# 4. Optimize the code# ... make improvements ...
# 5. Re-run benchmarks to measure impactmodestbench
# 6. Profile again to verifymodestbench analyze "npm test" > profile-after.txtConsider Context
Section titled “Consider Context”High percentage doesn’t always mean “needs optimization”:
- Expected hot paths: Core algorithms should take time
- Appropriate complexity: O(n²) algorithms might be fine for small n
- Already fast enough: Sometimes 5% of a fast program is still fast
Focus on functions where optimization would provide meaningful benefit.
Programmatic Usage
Section titled “Programmatic Usage”Use the profiler in your own tools:
import { runWithProfiling, parseProfile, filterProfile, ProfileHumanReporter, findPackageRoot,} from 'modestbench';
// Run profilingconst logPath = await runWithProfiling('npm test', { cwd: process.cwd(),});
// Parse resultsconst profileData = await parseProfile(logPath);
// Filter to user codeconst packageRoot = await findPackageRoot(process.cwd());const filtered = filterProfile( profileData, { smartDetection: true, minExecutionPercent: 2.0, topN: 50, }, packageRoot,);
// Display resultsconst reporter = new ProfileHumanReporter({ color: true });reporter.report(filtered);Troubleshooting
Section titled “Troubleshooting”No Profile Generated
Section titled “No Profile Generated”If you see “No profile log generated”:
- Ensure the command actually runs Node.js code
- Check that the process completes successfully
- Try with a simpler command first:
modestbench analyze "node --eval 'console.log(1)'"
No Functions Shown
Section titled “No Functions Shown”If the profiler shows 0 user functions:
- Your code might be too fast to profile (good problem!)
- Try running longer workloads
- Lower the
--min-percentthreshold - Check that
--filter-filepatterns match your code
Profile Data is Stale
Section titled “Profile Data is Stale”Profile logs are reused if they exist. To get fresh data, remove the isolate-*.log files created by Node.js’s V8 profiler (via the --cpu-prof flag that modestbench analyze uses under the hood):
# Remove old logsrm isolate-*.log
# Run profiling againmodestbench analyze "npm test"Next Steps
Section titled “Next Steps”- Read the Advanced Usage guide for benchmark patterns
- Learn about Historical Tracking to monitor improvements
- Explore the CLI Reference for all available options