packages/intl-durationformat/benchmark/README.md
This benchmark suite measures the performance of @formatjs/intl-durationformat against the native Intl.DurationFormat implementation (when available).
DurationFormat is used to format time durations in a locale-sensitive manner. Common use cases include:
This benchmark helps ensure the polyfill performs efficiently for real-world applications.
The benchmark includes the following scenarios:
Using Bazel:
bazel run //packages/intl-durationformat/benchmark:benchmark
Or using tsx directly from the root:
cd packages/intl-durationformat/benchmark
pnpm install
pnpm exec tsx benchmark.ts
To measure DurationFormat constructor performance (relevant to issue #4936):
bazel run //packages/intl-durationformat/benchmark:instantiation_benchmark
For detailed performance analysis and CPU profiling workflows, see PROFILE.md.
The benchmark uses tinybench and outputs:
Look for performance patterns across different styles and use cases to identify optimization opportunities.
Results from running on macOS (Apple Silicon) with Node.js v24.11.1:
┌─────────┬────────────────────────────────────────┬──────────────────┬──────────────────┬────────────────────────┬────────────────────────┬─────────┐
│ (index) │ Task name │ Latency avg (ns) │ Latency med (ns) │ Throughput avg (ops/s) │ Throughput med (ops/s) │ Samples │
├─────────┼────────────────────────────────────────┼──────────────────┼──────────────────┼────────────────────────┼────────────────────────┼─────────┤
│ 0 │ 'format short style (polyfill)' │ '86402 ± 0.18%' │ '85583 ± 2834.0' │ '11659 ± 0.14%' │ '11685 ± 380' │ 11574 │
│ 1 │ 'format long style (polyfill)' │ '88259 ± 0.19%' │ '87750 ± 3083.0' │ '11422 ± 0.15%' │ '11396 ± 392' │ 11331 │
│ 2 │ 'format narrow style (polyfill)' │ '83044 ± 0.20%' │ '82541 ± 1542.0' │ '12128 ± 0.13%' │ '12115 ± 224' │ 12042 │
│ 3 │ 'format digital style (polyfill)' │ '92334 ± 0.21%' │ '91958 ± 3583.0' │ '10918 ± 0.15%' │ '10875 ± 420' │ 10831 │
│ 4 │ 'formatToParts short style (polyfill)' │ '85850 ± 0.20%' │ '85958 ± 2875.0' │ '11741 ± 0.14%' │ '11634 ± 391' │ 11649 │
│ 5 │ 'format video durations (polyfill)' │ '29617 ± 0.18%' │ '29625 ± 750.00' │ '34157 ± 0.09%' │ '33755 ± 877' │ 33765 │
│ 6 │ 'format with milliseconds (polyfill)' │ '14021 ± 0.24%' │ '13958 ± 375.00' │ '72604 ± 0.06%' │ '71644 ± 1874' │ 71320 │
└─────────┴────────────────────────────────────────┴──────────────────┴──────────────────┴────────────────────────┴────────────────────────┴─────────┘
Note: Native Intl.DurationFormat is not yet widely available in browsers/runtimes, so most comparisons will be polyfill-only until native support becomes more common.
| Benchmark | Latency (μs) | Throughput (ops/s) | Notes |
|---|---|---|---|
| Short style | ~86 | ~11,659 | Default style, most common |
| Long style | ~88 | ~11,422 | Verbose format with full unit names |
| Narrow style | ~83 | ~12,128 | Most compact, slightly faster |
| Digital style | ~92 | ~10,918 | Time-like format (1:30:00) |
| formatToParts | ~86 | ~11,741 | Similar to format() performance |
| Video durations (digital) | ~30 | ~34,157 | Real-world scenario, 3x faster |
| Milliseconds formatting | ~14 | ~72,604 | Sub-second precision, very fast |
Style Performance:
Real-World Use Cases:
Optimization Opportunities:
Potential optimization strategies:
Number Format Caching:
Intl.NumberFormat instances per locale/optionsFast Paths:
Lazy Evaluation:
core.ts - Main DurationFormat implementationPartitionDurationFormatPattern.ts - Core formatting logicToDurationRecord.ts - Duration input validationGetDurationUnitOptions.ts - Unit options resolutionWhen optimizing DurationFormat: