bench: add benchmarks for parsing ISO 8601 durations
Some checks failed
ci / docsrs (push) Has been cancelled
ci / test-default (beta, ubuntu-latest, beta) (push) Has been cancelled
ci / rustfmt (push) Has been cancelled
ci / test-default (macos, macos-latest, stable) (push) Has been cancelled
ci / test-default (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-default (stable, ubuntu-latest, stable) (push) Has been cancelled
ci / test-all (macos, macos-latest, nightly) (push) Has been cancelled
ci / test-all (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-only-bundle (macos, macos-latest, nightly) (push) Has been cancelled
ci / test-only-bundle (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-core (macos, macos-latest, nightly) (push) Has been cancelled
ci / test-core (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-various-feature-combos (macos, macos-latest, nightly) (push) Has been cancelled
ci / test-various-feature-combos (nightly, ubuntu-latest, nightly) (push) Has been cancelled
ci / test-release (push) Has been cancelled
ci / test-doc (push) Has been cancelled
ci / test-bench (push) Has been cancelled
ci / test-miri (push) Has been cancelled
ci / win-msvc (push) Has been cancelled
ci / win-gnu (push) Has been cancelled
ci / msrv (push) Has been cancelled
ci / examples (push) Has been cancelled
ci / integrations (push) Has been cancelled
ci / time-zone-init (macos-latest) (push) Has been cancelled
ci / time-zone-init (ubuntu-24.04-arm) (push) Has been cancelled
ci / time-zone-init (ubuntu-latest) (push) Has been cancelled
ci / time-zone-init (windows-latest) (push) Has been cancelled
ci / cross (aarch64-linux-android) (push) Has been cancelled
ci / cross (aarch64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (i686-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc-unknown-linux-gnu) (push) Has been cancelled
ci / cross (powerpc64-unknown-linux-gnu) (push) Has been cancelled
ci / cross (s390x-unknown-linux-gnu) (push) Has been cancelled
ci / cross (x86_64-linux-android) (push) Has been cancelled
ci / riscv32imc-unknown-none-elf (push) Has been cancelled
ci / wasm32-wasip1 (push) Has been cancelled
ci / wasm32-unknown-emscripten (push) Has been cancelled
ci / wasm32-unknown-uknown (push) Has been cancelled
ci / generated (push) Has been cancelled

I'm kind of surprised I hadn't added these yet. But I think among Jiff,
Chrono and `time`, Jiff is the only one to support them.

I'm going to be touching the implementation (in persuit of adding
support for parsing/printing `std::time::Duration` directly), so I want
to make sure I am at least not regressing perf.
This commit is contained in:
Andrew Gallant 2025-10-29 21:31:31 -04:00
parent aae54ca665
commit 211a36d5ec
No known key found for this signature in database
GPG key ID: B2E3A4923F8B0D44

View file

@ -8,6 +8,7 @@ use crate::{benchmark, convert::ConvertFrom};
pub(super) fn define(c: &mut Criterion) {
parse_civil_datetime(c);
parse_friendly(c);
parse_iso8601_duration(c);
parse_rfc2822(c);
parse_strptime(c);
}
@ -217,6 +218,66 @@ fn parse_friendly(c: &mut Criterion) {
}
}
/// Benchmarks parsing an ISO 8601 duration. I think Jiff is alone in being
/// able to parse ISO 8601 durations (among itself, chrono and time).
fn parse_iso8601_duration(c: &mut Criterion) {
use jiff::{SignedDuration, Span, ToSpan};
const NAME: &str = "parse/iso8601_duration";
const TINY: &str = "PT2S";
const SHORT: &str = "PT2H30M";
const MEDIUM: &str = "P2DT5H30M";
const LONG: &str = "P2Y1M15DT5H59M1S";
const LONG_TIME: &str = "PT5H59M1.123456789S";
let benches = [
("tiny", TINY, 2.seconds()),
("short", SHORT, 2.hours().minutes(30)),
("medium", MEDIUM, 2.days().hours(5).minutes(30)),
(
"long",
LONG,
2.years().months(1).days(15).hours(5).minutes(59).seconds(1),
),
(
"long-time",
LONG_TIME,
5.hours()
.minutes(59)
.seconds(1)
.milliseconds(123)
.microseconds(456)
.nanoseconds(789),
),
];
for (kind, input, expected) in benches {
benchmark(c, format!("{NAME}/{kind}/span/jiff"), |b| {
b.iter(|| {
let got: Span = input.parse().unwrap();
assert_eq!(got.fieldwise(), expected.fieldwise());
})
});
}
let benches = [
("tiny", TINY, SignedDuration::new(2, 0)),
("short", SHORT, SignedDuration::new(2 * 60 * 60 + 30 * 60, 0)),
(
"long-time",
LONG_TIME,
SignedDuration::new(5 * 3600 + 59 * 60 + 1, 123_456_789),
),
];
for (kind, input, expected) in benches {
benchmark(c, format!("{NAME}/{kind}/duration/jiff"), |b| {
b.iter(|| {
let got: SignedDuration = input.parse().unwrap();
assert_eq!(got, expected);
})
});
}
}
/// Measures the time it takes to parse an RFC 2822 datetime as a timestamp.
fn parse_rfc2822(c: &mut Criterion) {
const NAME: &str = "parse/rfc2822";