Skip to content

Commit 972edf4

Browse files
authored
Performance improvements for Unitful conversion (#141)
1 parent f2bf5cb commit 972edf4

File tree

1 file changed

+16
-23
lines changed

1 file changed

+16
-23
lines changed

ext/DynamicQuantitiesUnitfulExt.jl

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ function get_si_units()
99
return (length=u"m", mass=u"kg", time=u"s", current=u"A", temperature=u"K", luminosity=u"cd", amount=u"mol")
1010
end
1111

12-
function validate_upreferred()
12+
@generated function validate_upreferred()
1313
si_units = get_si_units()
1414
for k in keys(si_units)
1515
if Unitful.upreferred(si_units[k]) !== si_units[k]
16-
error("Found custom `Unitful.preferunits`. This is not supported when interfacing Unitful and DynamicQuantities: you must leave the default `Unitful.upreferred`, which is the SI base units.")
16+
return :(error("Found custom `Unitful.preferunits`. This is not supported when interfacing Unitful and DynamicQuantities: you must leave the default `Unitful.upreferred`, which is the SI base units."))
1717
end
1818
end
1919
return true
@@ -53,29 +53,22 @@ for (_, _, Q) in ABSTRACT_QUANTITY_TYPES
5353
end
5454

5555
Base.convert(::Type{DynamicQuantities.Dimensions}, d::Unitful.Dimensions) = convert(DynamicQuantities.DEFAULT_DIM_TYPE, d)
56-
Base.convert(::Type{DynamicQuantities.Dimensions{R}}, d::Unitful.Dimensions{D}) where {R,D} =
57-
let
58-
validate_upreferred()
59-
cumulator = DynamicQuantities.Dimensions{R}()
60-
for dim in D
61-
dim_symbol = _map_dim_name_to_dynamic_units(typeof(dim))
62-
dim_power = dim.power
63-
cumulator *= DynamicQuantities.Dimensions(R; dim_symbol => dim_power)
64-
end
65-
cumulator
66-
end
6756

68-
function _map_dim_name_to_dynamic_units(::Type{Unitful.Dimension{D}}) where {D}
69-
# (We could do this automatically, but it's more obvious what we are doing this way.)
70-
D == :Length && return :length
71-
D == :Mass && return :mass
72-
D == :Time && return :time
73-
D == :Current && return :current
74-
D == :Temperature && return :temperature
75-
D == :Luminosity && return :luminosity
76-
D == :Amount && return :amount
77-
error("Unknown dimension: $D")
57+
function Base.convert(::Type{DynamicQuantities.Dimensions{R}}, d::Unitful.Dimensions{D}) where {R,D}
58+
validate_upreferred()
59+
return prod(Base.Fix1(_dynamic_dimension, R), D)
7860
end
7961

62+
function _dynamic_dimension(::Type{R}, dims::Unitful.Dimension{D}) where {R,D}
63+
DimType = DynamicQuantities.Dimensions{R}
64+
D == :Length && return DimType(length=dims.power)
65+
D == :Mass && return DimType(mass=dims.power)
66+
D == :Time && return DimType(time=dims.power)
67+
D == :Current && return DimType(current=dims.power)
68+
D == :Temperature && return DimType(temperature=dims.power)
69+
D == :Luminosity && return DimType(luminosity=dims.power)
70+
D == :Amount && return DimType(amount=dims.power)
71+
error("Unknown dimension: $D")
72+
end
8073

8174
end

0 commit comments

Comments
 (0)