packages/intl-durationformat/benchmark/PROFILE.md
This guide explains how to profile and analyze the performance of @formatjs/intl-durationformat using Node.js's built-in CPU profiler.
bazel run //packages/intl-durationformat/benchmark:profile_cpu
bazel run //packages/intl-durationformat/benchmark:analyze_profile
bazel run //packages/intl-durationformat/benchmark:profile_cpu
What this does:
--cpu-prof flag enabled.cpuprofile file in /tmp/Output:
Starting profiling...
Warming up...
Running profiled iterations...
Total time: XXXms
Completed 1800000 format() calls
Profile file location: /tmp/CPU.*.cpuprofile
bazel run //packages/intl-durationformat/benchmark:analyze_profile
The analyzer will automatically find and analyze the most recent .cpuprofile file in /tmp/.
# Using positional argument
bazel run //packages/intl-durationformat/benchmark:analyze_profile -- /tmp/CPU.20251223.120000.12345.0.001.cpuprofile
# Using --profile flag
bazel run //packages/intl-durationformat/benchmark:analyze_profile -- --profile /tmp/CPU.20251223.120000.12345.0.001.cpuprofile
# Using -p shorthand
bazel run //packages/intl-durationformat/benchmark:analyze_profile -- -p /tmp/CPU.20251223.120000.12345.0.001.cpuprofile
The analyzer provides two comprehensive views:
Shows individual functions sorted by CPU time:
Top 40 functions by CPU time (hit count):
==========================================
1. PartitionDurationFormatPattern [PartitionDurationFormatPattern.ts:42]
Hit count: 5234
File: file:///Users/.../intl-durationformat/src/abstract/PartitionDurationFormatPattern.ts
2. GetNumberFormatUnit [GetNumberFormatUnit.ts:15]
Hit count: 3456
File: file:///Users/.../ecma402-abstract/NumberFormat/GetNumberFormatUnit.ts
...
What each field means:
(anonymous) for unnamed functions)[filename:line]Aggregated view showing which files consume the most CPU time:
Top 20 files by CPU time:
=========================
1. intl-durationformat/src/abstract/PartitionDurationFormatPattern.ts: 8765 hits
2. ecma402-abstract/NumberFormat/format_to_parts.ts: 3210 hits
3. intl-durationformat/src/core.ts: 1543 hits
...
Filters:
node:internal).cpuprofile file from /tmp/Benefits:
.cpuprofile file in VS CodeBenefits:
node packages/intl-durationformat/benchmark/analyze-profile.ts /tmp/CPU.*.cpuprofile
| Target | Description |
|---|---|
profile | Quick timing test without profiling |
profile_cpu | CPU profiling with .cpuprofile output |
analyze_profile | Analyze .cpuprofile files |
benchmark | Full benchmark suite |
Look for:
Number Formatting
Intl.NumberFormat instances repeatedlyString Building
Unit Processing
Style Resolution
# Check if files exist
ls -lth /tmp/CPU.*.cpuprofile | head -5
# If empty, try running the profiler again
bazel run //packages/intl-durationformat/benchmark:profile_cpu
The profiler writes to /tmp/ by default. To change this:
BUILD.bazel and modify --cpu-prof-dir=/tmpanalyze-profile.ts line 106# Clean build cache
bazel clean
# Rebuild
bazel build //packages/intl-durationformat/benchmark:all
If you can't write to /tmp/:
# Use a different directory
mkdir -p ~/profiles
# Then update BUILD.bazel: --cpu-prof-dir=$HOME/profiles
Based on profiling results, consider these optimizations:
// Cache NumberFormat instances per locale/style
const formatCache = new Map<string, Intl.NumberFormat>()
// Pre-format 0-59 for time units (minutes, seconds)
const preFormattedValues = new Map<number, string>()
for (let i = 0; i < 60; i++) {
preFormattedValues.set(i, formatter.format(i))
}
// Special handling for digital format (most common for video)
if (style === 'digital' && isSimpleDuration(duration)) {
return formatDigitalFast(duration)
}
// Don't process units that are zero (unless display is 'always')
if (value === 0 && display !== 'always') {
continue
}
When adding profiling capabilities:
profile.ts