-
Notifications
You must be signed in to change notification settings - Fork 112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Units interface package #595
Comments
There have been several requests for such an interface package, so I think we should consider it. Unfortunately, I didn’t have much time in the past to really take part in the previous discussion:
Based on that, I think we would need a hierarchy of several packages to satisfy most users’ needs. Maybe we can base the discussion on the following proposal and refine it:
@giordano @Gregstrq @aplavin @mileslucas @tfiers What do you think about such a package hierarchy? Some other thoughts:
|
Given the "extension packages" feature of 1.9, splitting packages for the sake of loading time is not needed anymore. As for splitting for more modularity, I fully support it! |
I'm going to throw in my unsolicited opinion, as someone who's done a |
% julia --project=/tmp --startup-file=no -q
julia> @time @eval using Unitful
0.444807 seconds (924.10 k allocations: 64.710 MiB, 5.12% gc time) I have a 7-year old laptop. |
Interesting.
if I run it on a very modern desktop (different than the modern laptop used for the earlier measurements. But also Windows). edit Same powerful desktop:
In my global env (which isn't super bloated I'd say: https://github.com/tfiers/dotfiles/blob/174862c/.julia/environments/v1.8/Project.toml),
|
Are you always in a fresh session? If not, maybe there is something invalidating Unitful code? Also, do you use Revise? I see you use Windows, that may account for some slowness (I/O is pretty terrible on Windows). |
See my last edit (sorry for post-editing my comment):
(so no Revise or invalidations) Edit:
¹: Intel i7 10th gen (10510U), 16 GB Ram, ThinkPad X1 Yoga Gen 5 (2020 release), Win 10 Pro (and just for completeness, in a
) |
I would agree with @cstjean that making four way split is a bit too much. Also, I can't imagine someone using UnitfulCore without the arithmetics and convenience constructors. I stand by my initial proposal to only split out pkgdefaults. |
In my opinion, UnitfulCore is all that should be needed to implement something like JuliaStats/Distributions.jl#1413 (comment), which is the reason why this issue was opened. |
I'd like to add that I plan to experiment with an alternative units package (one with runtime units instead of units in the typesystem -- the goal is not necessarily performance, but rather ease of use and smaller type-signatures in compound datatypes). So it would be fantastic to have a kind of Ofc it's great if everyone's effort is concentrated on the same package instead of duplicated; but independent experimentation is worthwile too imho |
"Interface" packages and "Core" packages should have no purpose now that "package extensions" are available (or at least will be available in 1.9). |
For import times, indeed. |
Agreed. IMO "subdir" packages, in which you still use a single repo and can thus coordinate changes across multiple packages, reduce most but not all of this hassle. You still have to think through what you want to release, set up your CI scripts appropriately, etc. |
Another motivation for splitting the "interface" part is that it would enable support for "static units" (Unitful) and "dynamic units" (DynamicQuantities, @MilesCranmer) with the exact same code. Would be great to share all unit definitions, common functions like ustrip(), unit(), ... – basically everything that makes sense for both! |
^I would personally be 100% on board. (I don’t know if it’s possible, as the types are so different, including a variety of abstract types, but hopefully it is a possibility.) |
I thought more about the unification idea, and noticed that quite a lot of useful stuff is possible even without any buy-in from Unitful/DQ! Although, it would be cleaner with the buy-in. See my attempt at the common interface at https://github.com/JuliaAPlavin/UnitsBase.jl. Tests show some examples of what's possible: https://github.com/JuliaAPlavin/UnitsBase.jl/blob/master/test/runtests.jl.
The main usecase is that the package/function author can write using Unitful # can use DQ instead, but makes most sense to use type-stable Unitful when possible
using UnitsBase: ustrip, unit
g(x) = ustrip(u"m", x)
f(x) = ustrip(u"g/mm", x / u"km")
h(x) = "unit is $(unit(x))" and these functions work with either of the unit packages! So, the package code can be written using type-stable Unitful types, and used both with Unitful (most performant while units are type-stable) and DQ (most performant when units are dynamic) from user code. Let me know what you think of this approach. |
Nice work!! And yes there is buy-in from me on the DQ side. Can we move it to a shared Julia org to lower the bus factor? |
Totally, both the name and location of the repo are up to changes :) IMO would be best to have a lightweight UnitsBase with just two empty function definitions for now: https://github.com/JuliaAPlavin/UnitsBase.jl/blob/master/src/UnitsBase.jl. And no other content (some potentially to be added later). Then, both Unitful and DQ would depend on it and define methods for |
If Unitful devs also support this course of action, we can create that lightweight UnitsBase in a common Julia org. I guess JuliaMath fits well... |
JuliaMath sounds good (not sure who to ask for this?). Or maybe JuliaPhysics since that's where Measurements.jl and PhysicalConstants.jl live.
Sounds good to me. We can put it in the existing Unitful extension within DQ. My initial suggestions for more content would be |
I sent you an invite to JuliaPhysics. Years ago I also proposed to move this repo to the same org (#228), but it eventually was moved here and I think we're stuck with it, Andrew is the only admin of the repo and he doesn't seem to be very active on GitHub anymore. |
Awesome, thanks. Btw I'd be happy to rotate DynamicQuantities over there too, so we could have all the units and measurements packages under one umbrella org. |
using Unitful
currently takes 1 to 3 seconds1.This is fine if you're planning on actually using physical units in your Julia session.2
But it adds to the load time of downstream packages that offer optional Unitful support.
My concrete motivation for writing this issue is that I want to add Unitful support to Distributions.jl:
Doing that would require adding Unitful as a dependency to Distributions. But most Distributions.jl users will not use the new unitful distributions; and they would still get the added start-up latency.
That is why I propose to create a very lightweight package that defines just the interface/API for working with units in Julia. Something like
UnitfulCore
, orUnitsInterface.jl
.Downstream packages offering physical unit support would then load just that interface package.
(If the user wants to actually use the unit support, they have to explicitly be
using Unitful, DownstreamPkg
).This pattern has been applied before, e.g. in StaticArrays.jl. From its readme:
So my question to the maintainers of Unitful.jl is: would you be open to adding such an interface package as a dependency of Unitful, and moving some core types and functions to that package (or having them subtype from the package) ?
Footnotes
@time using Unitful
gives 1.0 seconds on replit, and between 1.6 and 2.6 seconds on my laptop (Julia 1.8). ↩Though a
@precompile_all_calls
block might be a good idea to add to src/ in any case. ↩The text was updated successfully, but these errors were encountered: