Noted by @dlebauer in #3925 (review):
there are a lot of calls in the PEcAn version of ud_convert (ud_are_convertible, as_units, set_units, drop_units) while the units package directly calls a C function. So I checked out the penalty, and found that the units implementation is about 20x faster and uses infinitely less memory.
bench::mark(
pecan = PEcAn.utils::ud_convert(42, "m", "km"),
units = units::ud_convert(42, "m", "km"),
iterations = 500
)
#> # A tibble: 2 × 6
#> expression min median `itr/sec` mem_alloc `gc/sec`
#> <bch:expr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl>
#> 1 pecan 142.35µs 151.56µs 6445. 6.44MB 52.0
#> 2 units 6.56µs 7.58µs 114353. 0B 229.
Consider replacing the as_units/set_units dance inside PEcAn.utils::ud_convert with a single call to units::ud_convert? This would (probably) capture the speed gains without requiring all other packages to add a direct {units} dependency.
One piece to consider: PEcAn.utils::ud_convert has a special case for difftime object that I don't think udunits::ud_convert knows how to handle. My impression is that's a little-used feature that could be retained without losing the everyday speedup, but I haven't checked in detail.
Noted by @dlebauer in #3925 (review):
Consider replacing the
as_units/set_unitsdance inside PEcAn.utils::ud_convert with a single call tounits::ud_convert? This would (probably) capture the speed gains without requiring all other packages to add a direct {units} dependency.One piece to consider: PEcAn.utils::ud_convert has a special case for
difftimeobject that I don't think udunits::ud_convert knows how to handle. My impression is that's a little-used feature that could be retained without losing the everyday speedup, but I haven't checked in detail.