typeof(a)
and typeof(b)
here do not tell you anything about performance of those types. Test1
and Test2{Float64}
are essentially just the names of the structs (a.k.a. types) you defined. In the Test3
example below, I get the same output from typeof
as your Test2
, but Type3
will perform badly because 2/3 of the fields are abstractly typed.
julia> struct Test3{T}
a::Real
b::T
c::AbstractString
end
julia> c = Test3(5.5, 5.6, "hello")
Test3{Float64}(5.5, 5.6, "hello")
julia> typeof(c)
Test3{Float64}
The point is that you want the fields of your struct to have concrete types (not abstract types). If you only need to allow Float64
, then it is fine to assign that type to a field directly. Parametric types allow the definition of multiple concrete types at once. The example below will be concretely typed parametrically.
julia> struct Test4{T}
a::T
b::T
c::String
end
julia> Test4(5.5, 5.6, "hello")
Test4{Float64}(5.5, 5.6, "hello")
julia> Test4("hello", "welcome", "home")
Test4{String}("hello", "welcome", "home")
The struct Test5
below is exactly the same as Test4
above except that Test5
will error if I try to enter something other than a subtype of Real
for the first two fields. There is no performance difference.
julia> struct Test5{T <: Real}
a::T
b::T
c::String
end
julia> Test5(5.5, 5.6, "hello")
Test5{Float64}(5.5, 5.6, "hello")
julia> Test5("hello", "welcome", "home")
ERROR: MethodError: no method matching Test5(::String, ::String, ::String)
Closest candidates are:
Test5(::T, ::T, ::String) where T<:Real at REPL[12]:2
Stacktrace:
[1] top-level scope
@ REPL[14]:1