Skip to content

Commit

Permalink
Implement diff_years kernels
Browse files Browse the repository at this point in the history
  • Loading branch information
jhorstmann committed Oct 31, 2023
1 parent 38e71b5 commit 74d7614
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 9 deletions.
45 changes: 41 additions & 4 deletions benches/bench_date_add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ use chrono::NaiveDateTime;
use chronoutil::shift_months;
use criterion::{criterion_group, criterion_main, Criterion, Throughput};

use packedtime_rs::{date_add_month_timestamp_millis, date_add_month_timestamp_millis_float, date_diff_month_timestamp_millis, date_diff_month_timestamp_millis_float};
use packedtime_rs::{
date_add_month_timestamp_millis, date_add_month_timestamp_millis_float,
date_diff_month_timestamp_millis, date_diff_month_timestamp_millis_float,
date_diff_year_timestamp_millis, date_diff_year_timestamp_millis_float,
};
use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};

Expand Down Expand Up @@ -52,7 +56,29 @@ fn bench_date_diff_month_float(start: &[f64], end: &[f64], output: &mut [i32]) {
});
}

#[inline(never)]
fn bench_date_diff_year(start: &[i64], end: &[i64], output: &mut [i32]) {
assert_eq!(start.len(), end.len());
assert_eq!(start.len(), output.len());
output
.iter_mut()
.zip(start.iter().copied().zip(end.iter().copied()))
.for_each(|(output, (start, end))| {
*output = date_diff_year_timestamp_millis(start, end);
});
}

#[inline(never)]
fn bench_date_diff_year_float(start: &[f64], end: &[f64], output: &mut [i32]) {
assert_eq!(start.len(), end.len());
assert_eq!(start.len(), output.len());
output
.iter_mut()
.zip(start.iter().copied().zip(end.iter().copied()))
.for_each(|(output, (start, end))| {
*output = date_diff_year_timestamp_millis_float(start, end);
});
}

#[inline(never)]
fn bench_date_add_month_chronoutil(input: &[i64], output: &mut [i64], months: i32) {
Expand Down Expand Up @@ -109,16 +135,27 @@ pub fn bench_date_add(c: &mut Criterion) {

c.benchmark_group("date_diff_month")
.throughput(Throughput::Bytes(
(BATCH_SIZE * 2 * std::mem::size_of::<i64>() + BATCH_SIZE*std::mem::size_of::<i32>()) as u64,
(BATCH_SIZE * 2 * std::mem::size_of::<i64>() + BATCH_SIZE * std::mem::size_of::<i32>())
as u64,
))
.bench_function("date_diff_month", |b| {
b.iter(|| bench_date_diff_month(&input, &input2, &mut output_diff))
})
.bench_function("date_diff_month_float", |b| {
b.iter(|| bench_date_diff_month_float(&input_float, &input_float2, &mut output_diff))
})
;
});

c.benchmark_group("date_diff_year")
.throughput(Throughput::Bytes(
(BATCH_SIZE * 2 * std::mem::size_of::<i64>() + BATCH_SIZE * std::mem::size_of::<i32>())
as u64,
))
.bench_function("date_diff_year", |b| {
b.iter(|| bench_date_diff_year(&input, &input2, &mut output_diff))
})
.bench_function("date_diff_year_float", |b| {
b.iter(|| bench_date_diff_year_float(&input_float, &input_float2, &mut output_diff))
});
}

criterion_group!(benches, bench_date_add);
Expand Down
45 changes: 45 additions & 0 deletions src/epoch_days.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,15 @@ impl EpochDays {
(y1 * 12 + m1) - (y0 * 12 + m0) - (d1 < d0) as i32
}

#[inline]
pub fn diff_years(&self, other: EpochDays) -> i32 {
let (y0, m0, d0) = self.to_ymd();
let (y1, m1, d1) = other.to_ymd();

// y1 - y0 - ((m1 < m0) | ((m1 == m0) & (d1 < d0))) as i32
y1 - y0 - ((m1, d1) < (m0, d0)) as i32
}

#[inline]
pub fn date_trunc_month(&self) -> Self {
let (y, m, d) = self.to_ymd();
Expand Down Expand Up @@ -332,6 +341,42 @@ mod tests {
);
}

#[test]
fn test_date_diff_year_epoch_days() {
assert_eq!(
EpochDays::from_ymd(2023, 10, 1).diff_years(EpochDays::from_ymd(2023, 10, 1)),
0
);
assert_eq!(
EpochDays::from_ymd(2023, 10, 1).diff_years(EpochDays::from_ymd(2023, 11, 1)),
0
);
assert_eq!(
EpochDays::from_ymd(2023, 1, 1).diff_years(EpochDays::from_ymd(2024, 1, 1)),
1
);
assert_eq!(
EpochDays::from_ymd(2023, 2, 28).diff_years(EpochDays::from_ymd(2024, 2, 28)),
1
);
assert_eq!(
EpochDays::from_ymd(2023, 2, 28).diff_years(EpochDays::from_ymd(2024, 2, 29)),
1
);
assert_eq!(
EpochDays::from_ymd(2023, 6, 15).diff_years(EpochDays::from_ymd(2024, 6, 14)),
0
);
assert_eq!(
EpochDays::from_ymd(2023, 6, 15).diff_years(EpochDays::from_ymd(2025, 6, 14)),
1
);
assert_eq!(
EpochDays::from_ymd(2023, 6, 15).diff_years(EpochDays::from_ymd(2025, 6, 16)),
2
);
}

#[test]
fn test_extract_year() {
assert_eq!(2022, EpochDays::from_ymd(2022, 1, 1).extract_year());
Expand Down
35 changes: 30 additions & 5 deletions src/kernels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,24 @@ pub fn date_diff_month_timestamp_millis_float(t0: f64, t1: f64) -> i32 {
(y1*12 + m1) - (y0*12 + m0) - ((ms1 < ms0) as i32)
}

#[inline]
pub fn date_diff_year_timestamp_millis(t0: i64, t1: i64) -> i32 {
let (y0, m0, ms0) = timestamp_to_year_month_millis_of_month(t0);
let (y1, m1, ms1) = timestamp_to_year_month_millis_of_month(t1);
y1 - y0 - (((m1, ms1) < (m0, ms0)) as i32)
}

#[inline]
pub fn date_diff_year_timestamp_millis_float(t0: f64, t1: f64) -> i32 {
let (y0, m0, ms0) = timestamp_to_year_month_millis_of_month_float(t0);
let (y1, m1, ms1) = timestamp_to_year_month_millis_of_month_float(t1);
y1 - y0 - (((m1, ms1) < (m0, ms0)) as i32)
}

#[cfg(test)]
mod tests {
use crate::epoch_days::EpochDays;
use crate::{
date_add_month_timestamp_millis, date_trunc_month_timestamp_millis,
date_trunc_quarter_timestamp_millis, date_trunc_year_timestamp_millis,
};
use crate::{date_add_month_timestamp_millis, date_diff_month_timestamp_millis, date_diff_year_timestamp_millis, date_trunc_month_timestamp_millis, date_trunc_quarter_timestamp_millis, date_trunc_year_timestamp_millis};
use chrono::{Datelike, NaiveDate, NaiveDateTime, NaiveTime};
use std::ops::Add;

Expand Down Expand Up @@ -264,8 +275,22 @@ mod tests {

#[test]
fn test_date_diff_months() {
// assert_eq!(epoch_day.add_months(-1), EpochDays::from_ymd(2022, 6, 30));
assert_eq!(date_diff_month_timestamp_millis(EpochDays::from_ymd(2023, 10, 1).to_timestamp_millis(), EpochDays::from_ymd(2023, 10, 1).to_timestamp_millis()), 0);
assert_eq!(date_diff_month_timestamp_millis(EpochDays::from_ymd(2023, 10, 1).to_timestamp_millis(), EpochDays::from_ymd(2023, 11, 1).to_timestamp_millis()), 1);
assert_eq!(date_diff_month_timestamp_millis(EpochDays::from_ymd(2023, 10, 15).to_timestamp_millis(), EpochDays::from_ymd(2023, 11, 14).to_timestamp_millis()), 0);
assert_eq!(date_diff_month_timestamp_millis(EpochDays::from_ymd(2023, 10, 15).to_timestamp_millis(), EpochDays::from_ymd(2023, 11, 15).to_timestamp_millis()), 1);
assert_eq!(date_diff_month_timestamp_millis(EpochDays::from_ymd(2023, 10, 15).to_timestamp_millis(), EpochDays::from_ymd(2023, 11, 16).to_timestamp_millis()), 1);
}

#[test]
fn test_date_diff_years() {
assert_eq!(date_diff_year_timestamp_millis(EpochDays::from_ymd(2023, 10, 1).to_timestamp_millis(), EpochDays::from_ymd(2023, 10, 1).to_timestamp_millis()), 0);
assert_eq!(date_diff_year_timestamp_millis(EpochDays::from_ymd(2023, 10, 1).to_timestamp_millis(), EpochDays::from_ymd(2023, 11, 1).to_timestamp_millis()), 0);
assert_eq!(date_diff_year_timestamp_millis(EpochDays::from_ymd(2023, 10, 15).to_timestamp_millis(), EpochDays::from_ymd(2024, 10, 14).to_timestamp_millis()), 0);
assert_eq!(date_diff_year_timestamp_millis(EpochDays::from_ymd(2023, 10, 15).to_timestamp_millis(), EpochDays::from_ymd(2024, 10, 15).to_timestamp_millis()), 1);
assert_eq!(date_diff_year_timestamp_millis(EpochDays::from_ymd(2023, 10, 15).to_timestamp_millis(), EpochDays::from_ymd(2024, 10, 16).to_timestamp_millis()), 1);
assert_eq!(date_diff_year_timestamp_millis(EpochDays::from_ymd(2024, 2, 29).to_timestamp_millis(), EpochDays::from_ymd(2025, 2, 28).to_timestamp_millis()), 0);
assert_eq!(date_diff_year_timestamp_millis(EpochDays::from_ymd(2024, 2, 29).to_timestamp_millis(), EpochDays::from_ymd(2025, 3, 1).to_timestamp_millis()), 1);
}

#[test]
Expand Down

0 comments on commit 74d7614

Please sign in to comment.