Overview
Thediff command compares two profiles to identify:
- REGRESSION: Methods that got slower (self% increased)
- IMPROVEMENT: Methods that got faster (self% decreased)
- NEW: Methods that appeared (absent in “before”)
- GONE: Methods that disappeared (absent in “after”)
Basic Usage
Compare Two Files
- Method name
- Before % → After %
- Delta (change in self%)
Diff compares self% (time spent in the method itself), not total time.
Window-Based Diff (Single File)
Compare two time windows in one JFR recording:- Before/after a configuration change in one session
- Compare low-load vs high-load periods
- Detect degradation during a long run
Interpreting Results
Regression
Method’s self% increased (got slower or more frequent):- HashMap resizing went from 12.3% to 28.7% of CPU time
- Absolute increase: +16.4 percentage points
- Increased load
- Larger data structures
- Code change introduced inefficiency
- JIT deoptimization
Improvement
Method’s self% decreased (got faster or less frequent):- JSON parsing dropped from 18.9% to 8.3%
- Absolute decrease: -10.6 percentage points
- Optimization applied
- Caching added
- Reduced call frequency
- JIT compilation kicked in
New
Method appeared in “after” but was absent in “before”:- Cache eviction became a hotspot (0% → 7.2%)
- New feature added
- Code path activated by workload change
- Method renamed/moved (appears as new)
- Sampling captured different execution
Gone
Method disappeared from “after” (was in “before”):- Method dropped from 14.5% to 0%
- Code removed/refactored
- Feature disabled
- Workload stopped triggering it
- Method inlined by JIT (merged into caller)
Filtering Changes
Minimum Delta Threshold
Hide small changes with--min-delta:
0.5 (0.5% threshold).
Use cases:
- Focus on significant regressions
- Ignore noise from JIT/GC variations
- CI gates for major changes only
Limit Output Rows
Cross-Format Diffs
Compare different profile formats:- Both have
cpu→ usecpu - Only one has
cpu→ use that side’s default - Explicit
--eventflag overrides
Event Type Selection
Explicit Event
Auto-Detection
If both files have the same event, it’s selected automatically:Combining with Filters
Thread-Specific Diff
Fully-Qualified Names
java.util.HashMap.resize).
Why? Disambiguates methods with the same short name:
com.example.Service.processcom.util.Service.process
--fqn, these merge into Service.process.
Time Window + Thread
Real-World Workflows
CI Regression Gate
See CI Integration for details.Load Test Comparison
NEW under high load.
Before/After Optimization
- IMPROVEMENT: Cache hit paths get faster
- NEW: Cache eviction logic appears
- GONE: Expensive computations disappear
Rolling Upgrade Validation
Diff Output Structure
Section Order
- REGRESSION — Sorted by largest delta (highest increase)
- IMPROVEMENT — Sorted by largest delta (biggest decrease)
- NEW — Sorted by self% in “after”
- GONE — Sorted by self% in “before”
No Changes
If no methods cross the--min-delta threshold:
Empty Profiles
If either side is empty:Advanced Use Cases
Multi-Stage Diff
Compare three profiles:Split and Compare
Use Starlark to split a recording and compare halves:Automated Regression Reports
Generate a report:Common Pitfalls
JIT Effects
JIT compilation changes method visibility:- Cold start: Methods appear in early samples
- Warm JVM: Methods disappear after inlining
Sampling Noise
Short profiles have high variance:--min-delta:
Different Workloads
Comparing incompatible workloads produces misleading results:Mixed Event Types
Comparing CPU vs wall-clock:--event to ensure same event type:
Related Workflows
- Time Range Filtering — Window-based diffs
- Thread Filtering — Per-thread diff
- CI Integration — Automated regression detection
- Starlark Scripting — Custom diff logic