Repository navigation
isoweek()/isoyear(): use convertDate() instead of format() - #7926
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #7926 +/- ##
=========================================
Coverage ? 99.02%
=========================================
Files ? 88
Lines ? 17388
Branches ? 0
=========================================
Hits ? 17218
Misses ? 170
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Change LGTM. How much code would we bring in with the C code? Could you maybe compare it with |
Generated via commit a6f8c6a Download link for the artifact containing the test results: ↓ atime-results.zip
|
|
It's only about 20 lines added to src/idatetime.c pure C library(data.table, warn.conflicts = FALSE)
setDTthreads(1L)
set.seed(349)
x <- sample(as.Date("2026-10-17") - 0:5000, 1e6, replace = TRUE)
bench::mark(isoweek(x), isoyear(x), check = FALSE, min_iterations = 10)
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 isoweek(x) 7.02ms 7.09ms 140. 7.65MB 46.7
#> 2 isoyear(x) 5.9ms 5.94ms 168. 7.63MB 66.5Created on 2026-10-18 with reprex v2.1.1 I didn't know of fasttime and fastymd, but only the latter seems relevant. However, it also doesn't have Basic idea one could copy as well: const unsigned mp = (5 * doy + 2) / 153; // month index, March = 0
const unsigned d = doy - (153 * mp + 2) / 5 + 1; // day of month
const unsigned m = mp + (mp < 10 ? 3 : -9); // 1..12library(data.table, warn.conflicts = FALSE)
setDTthreads(1L)
set.seed(349)
x = sample(as.Date("2026-10-17") - 0:5000, 1e6, replace = TRUE)
bench::mark(fastymd::get_year(x), year(x), min_iterations = 10)
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 fastymd::get_year(x) 5.09ms 5.21ms 190. 15.3MB 373.
#> 2 year(x) 3.41ms 3.46ms 289. 7.65MB 73.5
bench::mark(fastymd::get_month(x), month(x), min_iterations = 10)
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 fastymd::get_month(x) 5.13ms 5.22ms 191. 15.26MB 332.
#> 2 month(x) 17.64ms 17.75ms 56.2 7.63MB 12.8
bench::mark(fastymd::get_mday(x), mday(x), min_iterations = 10)
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 fastymd::get_mday(x) 5.5ms 5.56ms 178. 15.26MB 207.
#> 2 mday(x) 17.8ms 18.29ms 54.4 7.63MB 12.4Created on 2026-10-18 with reprex v2.1.1 |

Follows the implementation that was commented out and mentioned in the wiki article. I tried out a rough version in C that would speed it up by another 2x, not sure if it's worth it, perhaps as a follow-up.
master
Created on 2026-10-17 with reprex v2.1.1
PR
Created on 2026-10-17 with reprex v2.1.1