Skip to content

Conversation

DavisVaughan
Copy link
Member

@DavisVaughan DavisVaughan commented Oct 3, 2025

The id argument in combination with the msg %<~% delayed assign operator used internally is awesome. It lets us totally avoid lifecycle_message() in deprecate_soft() and deprecate_warn(), which are expensive.

This PR documents this usage of id, and adds a test so we hopefully don't regress on this in the future. I also added a comment in 26fa727 about this.

# Without `id` (CRAN vs this PR with all the other fixes so far)

cross::bench_versions(pkgs = c("lifecycle", "r-lib/lifecycle#197"), \() {
  library(lifecycle)
  
  # trigger the 8 hour warning once
  deprecate_soft("1.1.0", I("my thing"), details = "for this")

  bench::mark(
    deprecate_soft("1.1.0", I("my thing"), details = "for this"),
    iterations = 100000
  )
})
#> # A tibble: 2 × 7
#>   pkg                 expression                      min  median `itr/sec` mem_alloc `gc/sec`
#>   <chr>               <bch:expr>                    <bch> <bch:t>     <dbl> <bch:byt>    <dbl>
#> 1 lifecycle           "deprecate_soft(\"1.1.0\", I… 224µs 239.8µs     4046.    8.55KB     42.0
#> 2 r-lib/lifecycle#197 "deprecate_soft(\"1.1.0\", I…  43µs  44.4µs    21872.    8.56KB     59.7
# With `id` (CRAN vs this PR with all the other fixes so far)

cross::bench_versions(pkgs = c("lifecycle", "r-lib/lifecycle#197"), \() {
  library(lifecycle)
  
  # trigger the 8 hour warning once
  deprecate_soft("1.1.0", I("my thing"), details = "for this", id = "foo")

  bench::mark(
    deprecate_soft("1.1.0", I("my thing"), details = "for this", id = "foo"),
    iterations = 100000
  )
})
#> # A tibble: 2 × 7
#>   pkg                 expression                      min  median `itr/sec` mem_alloc `gc/sec`
#>   <chr>               <bch:expr>                  <bch:t> <bch:t>     <dbl> <bch:byt>    <dbl>
#> 1 lifecycle           "deprecate_soft(\"1.1.0\",…   145µs 154.9µs     6316.    8.55KB     44.1
#> 2 r-lib/lifecycle#197 "deprecate_soft(\"1.1.0\",…  31.7µs  33.1µs    29172.    8.56KB     67.0

When a once per session message has already been thrown and id is supplied, we are getting very close to "just early exiting" - almost all of the time is now in signalCondition() due to it not being as lazy as we'd hope.

profvis::profvis(for (i in 1:100000) deprecate_soft("1.1.0", I("my thing"), details = "for this", id = "foo"))
Screenshot 2025-10-03 at 1 46 49 PM Screenshot 2025-10-03 at 1 47 43 PM

…essage

Resulting in much faster repeated calls to `deprecate_soft()` and `deprecate_warn()`
@DavisVaughan DavisVaughan merged commit 9d5e66a into main Oct 3, 2025
14 checks passed
@DavisVaughan DavisVaughan deleted the feature/id branch October 3, 2025 17:52
@DavisVaughan DavisVaughan mentioned this pull request Oct 3, 2025
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.

1 participant