Unitful abstract types as arguments to function

I would like to write a function that takes as argument an array of a Unitful.Quantity. Ideally with a type derived from a an abstract type such as AbstractFloat, dimensions to be defined, and any units. Something like this is not working:

using Unitful

function myfunc(a::Array{Quantity{<:AbstractFloat}, 2})
    do_some_work(a)
end

The idea is that the function can be called with any 2D array of a Quantity type based on AbstractFloat, regardless of the units. I can get it to work by just specifying a::Array, but feel that specifying the type and dimensions will lead to better optimisation.

Also tried formulations such as these, and it did not work:

function myfunc(a::Array{D, 2}) where D <: Quantity{AbstractFloat}
    do_some_work(a)
end

Why do you feel that specifying the type and dimension will lead to better optimisation? Can you show benchmarks that demonstrate the slowdown? Generally, restricting types of function arguments should not have a performance impact.

1 Like

I don’t have any benchmarks that demonstrate a slowdown (in fact, my tests showed no significant difference). I am just beginning in Julia, and from reading the performance tips on the manual I thought it was always better for the compiler to declare the type. Is this not true? About the dimensions, is more of a logical thing: I would like it to be easier for a human to parse the argument list, and I would also like to prevent the function being called with an array of a different size (and then failing somewhere else).

That’s fair enough, although in fact the performance tips section in the manual says the opposite:

In many languages with optional type declarations, adding declarations is the principal way to make code run faster. This is not the case in Julia.

So unless you’re in one of those specific instances cited in the manual where annotations can help, you probably shouldn’t worry. Based on the fact that you say you don’t see a slowdown, it looks like you’re not in one of those situations.

More generally, it is usually a good idea not to type your code too restrictively in order to facilitate code reuse - this principle is what allows many independently developed Julia packages to work together seamlessly, without their authors ever explicitly planning for this.

1 Like