Reputation:
From Performance Tips:
When working with parameterized types, including arrays, it is best to avoid parameterizing with abstract types where possible.
Suppose you're writing a function that requires a Vector
, and with each use of the function, the Vector
can contain different types.
function selection_sort!(unsorted_vect::AbstractVector)
# Code to sort.
end
names = String["Sarah","Kathy","Amber"]
unsorted_fibonacci = Int32[8, 1, 34, 21, 3, 5, 0, 13, 2, 1]
selection_sort!(names)
selection_sort!(unsorted_fibonacci)
When using selection_sort!()
the first time, the Vector
contains String
, the second time Int32
.
The function knows it's getting an AbstractVector
, but it doesn't know the type of elements.
selection_sort!(unsorted_vect::AbstractVector{Real})
?The same section also says:
If you cannot avoid containers with abstract value types, it is sometimes better to parametrize with Any to avoid runtime type checking. E.g. IdDict{Any, Any} performs better than IdDict{Type, Vector}
function selection_sort!(unsorted_vect::AbstractVector{Any})
If so, why do the sorting algorithms just use AbstractVector
?
function sort!(v::AbstractVector, # left out other parameters)
Upvotes: 2
Views: 154
Reputation: 42214
What you need is:
function selection_sort!(unsorted_vect::AbstractVector{T}) where T
# Code to sort.
end
In this way you have an abstract type for the container (and hence any container will get accepted).
Yet those containers con be non-abstract - because they can have a concrete type for their elements - T
. As noted by Bogumil - if in the body code you do not need the type T
you could do function selection_sort!(unsorted_vect::AbstractVector)
instead.
However, this is just a limit for argument types. Julia would be as happy as to have function selection_sort!(unsorted_vect)
and the code would be as efficient.
What will really matter are the types of arguments. Consider the following 3 variables:
a = Vector{Float64}(rand(10))
b = Vector{Union{Float64,Int}}(rand(10))
c = Vector{Any}(rand(10))
a
is a typed container, b
is a small-union type container and c
is an abstract container. Let us have a look on what is happening with the performance:
julia> @btime minimum($a);
18.530 ns (0 allocations: 0 bytes)
julia> @btime minimum($b);
28.600 ns (0 allocations: 0 bytes)
julia> @btime minimum($c);
241.071 ns (9 allocations: 144 bytes)
The variable c
requires value unboxing (due to unknown element type) and hence the performance is degraded by an order of magnitude.
In conclusion, it is the parameter type what actually matters.
Upvotes: 1