mirror of
https://github.com/chronotope/chrono.git
synced 2025-09-27 13:01:37 +00:00
222 lines
7.2 KiB
Rust
222 lines
7.2 KiB
Rust
//! Benchmarks for chrono that just depend on std
|
|
|
|
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
|
|
|
|
use chrono::format::StrftimeItems;
|
|
use chrono::prelude::*;
|
|
#[cfg(feature = "unstable-locales")]
|
|
use chrono::Locale;
|
|
use chrono::{DateTime, FixedOffset, Local, Utc, __BenchYearFlags};
|
|
|
|
fn bench_datetime_parse_from_rfc2822(c: &mut Criterion) {
|
|
c.bench_function("bench_datetime_parse_from_rfc2822", |b| {
|
|
b.iter(|| {
|
|
let str = black_box("Wed, 18 Feb 2015 23:16:09 +0000");
|
|
DateTime::parse_from_rfc2822(str).unwrap()
|
|
})
|
|
});
|
|
}
|
|
|
|
fn bench_datetime_parse_from_rfc3339(c: &mut Criterion) {
|
|
c.bench_function("bench_datetime_parse_from_rfc3339", |b| {
|
|
b.iter(|| {
|
|
let str = black_box("2015-02-18T23:59:60.234567+05:00");
|
|
DateTime::parse_from_rfc3339(str).unwrap()
|
|
})
|
|
});
|
|
}
|
|
|
|
fn bench_datetime_from_str(c: &mut Criterion) {
|
|
c.bench_function("bench_datetime_from_str", |b| {
|
|
b.iter(|| {
|
|
use std::str::FromStr;
|
|
let str = black_box("2019-03-30T18:46:57.193Z");
|
|
DateTime::<Utc>::from_str(str).unwrap()
|
|
})
|
|
});
|
|
}
|
|
|
|
fn bench_datetime_to_rfc2822(c: &mut Criterion) {
|
|
let pst = FixedOffset::east_opt(8 * 60 * 60).unwrap();
|
|
let dt = pst
|
|
.from_local_datetime(
|
|
&NaiveDate::from_ymd_opt(2018, 1, 11)
|
|
.unwrap()
|
|
.and_hms_nano_opt(10, 5, 13, 84_660_000)
|
|
.unwrap(),
|
|
)
|
|
.unwrap();
|
|
c.bench_function("bench_datetime_to_rfc2822", |b| b.iter(|| black_box(dt).to_rfc2822()));
|
|
}
|
|
|
|
fn bench_datetime_to_rfc3339(c: &mut Criterion) {
|
|
let pst = FixedOffset::east_opt(8 * 60 * 60).unwrap();
|
|
let dt = pst
|
|
.from_local_datetime(
|
|
&NaiveDate::from_ymd_opt(2018, 1, 11)
|
|
.unwrap()
|
|
.and_hms_nano_opt(10, 5, 13, 84_660_000)
|
|
.unwrap(),
|
|
)
|
|
.unwrap();
|
|
c.bench_function("bench_datetime_to_rfc3339", |b| b.iter(|| black_box(dt).to_rfc3339()));
|
|
}
|
|
|
|
fn bench_datetime_to_rfc3339_opts(c: &mut Criterion) {
|
|
let pst = FixedOffset::east_opt(8 * 60 * 60).unwrap();
|
|
let dt = pst
|
|
.from_local_datetime(
|
|
&NaiveDate::from_ymd_opt(2018, 1, 11)
|
|
.unwrap()
|
|
.and_hms_nano_opt(10, 5, 13, 84_660_000)
|
|
.unwrap(),
|
|
)
|
|
.unwrap();
|
|
c.bench_function("bench_datetime_to_rfc3339_opts", |b| {
|
|
b.iter(|| black_box(dt).to_rfc3339_opts(SecondsFormat::Nanos, true))
|
|
});
|
|
}
|
|
|
|
fn bench_year_flags_from_year(c: &mut Criterion) {
|
|
c.bench_function("bench_year_flags_from_year", |b| {
|
|
b.iter(|| {
|
|
for year in -999i32..1000 {
|
|
let _ = __BenchYearFlags::from_year(black_box(year));
|
|
}
|
|
})
|
|
});
|
|
}
|
|
|
|
fn bench_get_local_time(c: &mut Criterion) {
|
|
c.bench_function("bench_get_local_time", |b| {
|
|
b.iter(|| {
|
|
let _ = Local::now();
|
|
})
|
|
});
|
|
}
|
|
|
|
/// Returns the number of multiples of `div` in the range `start..end`.
|
|
///
|
|
/// If the range `start..end` is back-to-front, i.e. `start` is greater than `end`, the
|
|
/// behaviour is defined by the following equation:
|
|
/// `in_between(start, end, div) == - in_between(end, start, div)`.
|
|
///
|
|
/// When `div` is 1, this is equivalent to `end - start`, i.e. the length of `start..end`.
|
|
///
|
|
/// # Panics
|
|
///
|
|
/// Panics if `div` is not positive.
|
|
fn in_between(start: i32, end: i32, div: i32) -> i32 {
|
|
assert!(div > 0, "in_between: nonpositive div = {}", div);
|
|
let start = (start.div_euclid(div), start.rem_euclid(div));
|
|
let end = (end.div_euclid(div), end.rem_euclid(div));
|
|
// The lowest multiple of `div` greater than or equal to `start`, divided.
|
|
let start = start.0 + (start.1 != 0) as i32;
|
|
// The lowest multiple of `div` greater than or equal to `end`, divided.
|
|
let end = end.0 + (end.1 != 0) as i32;
|
|
end - start
|
|
}
|
|
|
|
/// Alternative implementation to `Datelike::num_days_from_ce`
|
|
fn num_days_from_ce_alt<Date: Datelike>(date: &Date) -> i32 {
|
|
let year = date.year();
|
|
let diff = move |div| in_between(1, year, div);
|
|
// 365 days a year, one more in leap years. In the gregorian calendar, leap years are all
|
|
// the multiples of 4 except multiples of 100 but including multiples of 400.
|
|
date.ordinal() as i32 + 365 * diff(1) + diff(4) - diff(100) + diff(400)
|
|
}
|
|
|
|
fn bench_num_days_from_ce(c: &mut Criterion) {
|
|
let mut group = c.benchmark_group("num_days_from_ce");
|
|
for year in &[1, 500, 2000, 2019] {
|
|
let d = NaiveDate::from_ymd_opt(*year, 1, 1).unwrap();
|
|
group.bench_with_input(BenchmarkId::new("new", year), &d, |b, y| {
|
|
b.iter(|| num_days_from_ce_alt(y))
|
|
});
|
|
group.bench_with_input(BenchmarkId::new("classic", year), &d, |b, y| {
|
|
b.iter(|| y.num_days_from_ce())
|
|
});
|
|
}
|
|
}
|
|
|
|
fn bench_parse_strftime(c: &mut Criterion) {
|
|
c.bench_function("bench_parse_strftime", |b| {
|
|
b.iter(|| {
|
|
let str = black_box("%a, %d %b %Y %H:%M:%S GMT");
|
|
let items = StrftimeItems::new(str);
|
|
black_box(items.collect::<Vec<_>>());
|
|
})
|
|
});
|
|
}
|
|
|
|
#[cfg(feature = "unstable-locales")]
|
|
fn bench_parse_strftime_localized(c: &mut Criterion) {
|
|
c.bench_function("bench_parse_strftime_localized", |b| {
|
|
b.iter(|| {
|
|
let str = black_box("%a, %d %b %Y %H:%M:%S GMT");
|
|
let items = StrftimeItems::new_with_locale(str, Locale::nl_NL);
|
|
black_box(items.collect::<Vec<_>>());
|
|
})
|
|
});
|
|
}
|
|
|
|
fn bench_format(c: &mut Criterion) {
|
|
let dt = Local::now();
|
|
c.bench_function("bench_format", |b| {
|
|
b.iter(|| format!("{}", black_box(dt).format("%Y-%m-%dT%H:%M:%S%.f%:z")))
|
|
});
|
|
}
|
|
|
|
fn bench_format_with_items(c: &mut Criterion) {
|
|
let dt = Local::now();
|
|
let items: Vec<_> = StrftimeItems::new("%Y-%m-%dT%H:%M:%S%.f%:z").collect();
|
|
c.bench_function("bench_format_with_items", |b| {
|
|
b.iter(|| format!("{}", black_box(dt).format_with_items(items.iter())))
|
|
});
|
|
}
|
|
|
|
fn bench_format_manual(c: &mut Criterion) {
|
|
let dt = Local::now();
|
|
c.bench_function("bench_format_manual", |b| {
|
|
b.iter(|| {
|
|
black_box(dt);
|
|
format!(
|
|
"{:04}-{:02}-{:02}T{:02}:{:02}:{:02}.{:09}{:+02}:{:02}",
|
|
dt.year(),
|
|
dt.month(),
|
|
dt.day(),
|
|
dt.hour(),
|
|
dt.minute(),
|
|
dt.second(),
|
|
dt.nanosecond(),
|
|
dt.offset().fix().local_minus_utc() / 3600,
|
|
dt.offset().fix().local_minus_utc() / 60,
|
|
)
|
|
})
|
|
});
|
|
}
|
|
criterion_group!(
|
|
benches,
|
|
bench_datetime_parse_from_rfc2822,
|
|
bench_datetime_parse_from_rfc3339,
|
|
bench_datetime_from_str,
|
|
bench_datetime_to_rfc2822,
|
|
bench_datetime_to_rfc3339,
|
|
bench_datetime_to_rfc3339_opts,
|
|
bench_year_flags_from_year,
|
|
bench_num_days_from_ce,
|
|
bench_get_local_time,
|
|
bench_parse_strftime,
|
|
bench_format,
|
|
bench_format_with_items,
|
|
bench_format_manual,
|
|
);
|
|
|
|
#[cfg(feature = "unstable-locales")]
|
|
criterion_group!(unstable_locales, bench_parse_strftime_localized,);
|
|
|
|
#[cfg(not(feature = "unstable-locales"))]
|
|
criterion_main!(benches);
|
|
#[cfg(feature = "unstable-locales")]
|
|
criterion_main!(benches, unstable_locales);
|