Skip to content

Conversation

@mikmart
Copy link
Contributor

@mikmart mikmart commented May 1, 2025

I noticed the fastymd package hitting CRAN recently. One of its features is fast leap year calculations, which made me wonder how lubridate stacks up.

Currently leap_year() is pure R and is relatively speaking quite slow. With the lubridate main branch:

library(microbenchmark)

set.seed(42)
years <- sample(4000, 1e4, replace = TRUE)

microbenchmark(
  fastymd::is_leap(years),
  lubridate::leap_year(years),
  times = 1e4
)
#> Unit: microseconds
#>                         expr   min    lq       mean median     uq      max neval cld
#>      fastymd::is_leap(years)  29.4  47.8   65.64309   52.6   64.2  11538.7 10000  a 
#>  lubridate::leap_year(years) 792.3 986.5 1203.30433 1020.2 1139.0 298644.7 10000   b

Created on 2025-05-01 with reprex v2.1.1

This PR moves the leap year calculation to C, simply wrapping the IS_LEAP macro already used elsewhere in the codebase. With it I see a roughly 30-fold performance increase on my machine:

library(microbenchmark)

set.seed(42)
years <- sample(4000, 1e4, replace = TRUE)

microbenchmark(
  fastymd::is_leap(years),
  lubridate::leap_year(years),
  times = 1e4
)
#> Unit: microseconds
#>                         expr  min   lq     mean median   uq    max neval cld
#>      fastymd::is_leap(years) 29.2 44.1 64.90436   48.4 55.8  20797 10000   a
#>  lubridate::leap_year(years) 15.6 30.4 72.39227   34.6 40.2 310873 10000   a

Created on 2025-05-01 with reprex v2.1.1

@vspinu
Copy link
Member

vspinu commented May 11, 2025

Thanks @mikmart! This is nice.

@vspinu vspinu merged commit c073b81 into tidyverse:main May 11, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants