Revision control

Copy as Markdown

Other Tools

#![expect(
clippy::large_stack_frames,
reason = "iterating over large array; does not cause stack overflow"
)]
use std::hint::black_box as bb;
use std::sync::LazyLock;
use criterion::Bencher;
use time::ext::{NumericalDuration, NumericalStdDuration};
use time::macros::date;
use time::{Date, Time};
/// Generate a representative sample of all dates.
///
/// The ratio of month sizes, week sizes, year sign, leap years, etc. are all identical to the full
/// range. This ensures that benchmarks accurately reflect random data.
//
// Note that this is a _very_ large array (over 1 MiB), so we silence the warning about large stack
// frames at the top of this file.
fn representative_dates() -> [Date; 292_194] {
static DATES: LazyLock<[Date; 292_194]> = LazyLock::new(|| {
let mut dates = [Date::MIN; _];
let mut current = date!(-0400-01-01);
let mut i = 0;
while current < date!(0400-01-01) {
dates[i] = current;
current = current.next_day().expect("date is in range");
i += 1;
}
crate::shuffle(dates)
});
*DATES
}
setup_benchmark! {
"Date",
fn noop(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(date);
}
});
}
fn noop_windows(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates().windows(2) {
let first = date[0];
let second = date[1];
let _ = bb((bb(first), bb(second)));
}
});
}
fn from_calendar_date(ben: &mut Bencher<'_>) {
let dates = representative_dates().map(Date::to_calendar_date);
ben.iter(|| {
for (year, month, day) in dates {
let _ = bb(Date::from_calendar_date(bb(year), bb(month), bb(day)));
}
});
}
fn from_ordinal_date(ben: &mut Bencher<'_>) {
let dates = representative_dates().map(Date::to_ordinal_date);
ben.iter(|| {
for (year, ordinal) in dates {
let _ = bb(Date::from_ordinal_date(bb(year), bb(ordinal)));
}
});
}
fn from_iso_week_date(ben: &mut Bencher<'_>) {
let dates = representative_dates().map(Date::to_iso_week_date);
ben.iter(|| {
for (year, week, weekday) in dates {
let _ = bb(Date::from_iso_week_date(bb(year), bb(week), bb(weekday)));
}
});
}
fn from_julian_day(ben: &mut Bencher<'_>) {
let dates = representative_dates().map(Date::to_julian_day);
ben.iter(|| {
for julian_day in dates {
let _ = bb(Date::from_julian_day(bb(julian_day)));
}
});
}
fn year(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).year());
}
});
}
fn month(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).month());
}
});
}
fn day(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).day());
}
});
}
fn ordinal(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).ordinal());
}
});
}
fn iso_week(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).iso_week());
}
});
}
fn sunday_based_week(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).sunday_based_week());
}
});
}
fn monday_based_week(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).monday_based_week());
}
});
}
fn to_calendar_date(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).to_calendar_date());
}
});
}
fn to_ordinal_date(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).to_ordinal_date());
}
});
}
fn to_iso_week_date(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).to_iso_week_date());
}
});
}
fn weekday(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).weekday());
}
});
}
fn next_day(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).next_day());
}
});
}
fn previous_day(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).previous_day());
}
});
}
fn to_julian_day(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).to_julian_day());
}
});
}
fn midnight(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).midnight());
}
});
}
fn with_time(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).with_time(bb(Time::MIDNIGHT)));
}
});
}
fn with_hms(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).with_hms(bb(0), bb(0), bb(0)));
}
});
}
fn with_hms_milli(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).with_hms_milli(bb(0), bb(0), bb(0), bb(0)));
}
});
}
fn with_hms_micro(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).with_hms_micro(bb(0), bb(0), bb(0), bb(0)));
}
});
}
fn with_hms_nano(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date).with_hms_nano(bb(0), bb(0), bb(0), bb(0)));
}
});
}
fn add(ben: &mut Bencher<'_>) {
let dt = 5.days();
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date) + bb(dt));
}
});
}
fn add_std(ben: &mut Bencher<'_>) {
let dt = 5.std_days();
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date) - bb(dt));
}
});
}
fn add_assign(ben: &mut Bencher<'_>) {
let dt = 1.days();
ben.iter(|| {
for mut date in representative_dates() {
date += bb(dt);
let _ = bb(date);
}
});
}
fn add_assign_std(ben: &mut Bencher<'_>) {
let dt = 1.std_days();
ben.iter(|| {
for mut date in representative_dates() {
date += bb(dt);
let _ = bb(date);
}
});
}
fn sub(ben: &mut Bencher<'_>) {
let dt = 5.days();
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date) - bb(dt));
}
});
}
fn sub_std(ben: &mut Bencher<'_>) {
let dt = 5.std_days();
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date) - bb(dt));
}
});
}
fn sub_assign(ben: &mut Bencher<'_>) {
let dt = 1.days();
ben.iter(|| {
for mut date in representative_dates() {
date -= bb(dt);
let _ = bb(date);
}
});
}
fn sub_assign_std(ben: &mut Bencher<'_>) {
let dt = 1.std_days();
ben.iter(|| {
for mut date in representative_dates() {
date -= bb(dt);
let _ = bb(date);
}
});
}
fn sub_self(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates() {
let _ = bb(bb(date) - bb(date));
}
});
}
fn partial_ord(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates().windows(2) {
let first = date[0];
let second = date[1];
let _ = bb(bb(first).partial_cmp(&bb(second)));
}
});
}
fn ord(ben: &mut Bencher<'_>) {
ben.iter(|| {
for date in representative_dates().windows(2) {
let first = date[0];
let second = date[1];
let _ = bb(bb(first).cmp(&bb(second)));
}
});
}
}