Avoiding Julia type-instabilities
Attached NextJournal's link where I explained who I avoided type-instabilities of complex Julia structures
I have just made a blog post (check it out here!) with my own experience trying to avoid type-instabilities of Julia structs.
Type-instability of Parametrized Structs
First create all the data for our struct attributes.
We are going to create singletons of abstract type Car
.
abstract type Car end
struct Volvo <: Car end
struct Mazda <: Car end
Then consider the Struct
where we want to store our data.
So, lets define a struct as
abstract type GeneralStruct end
struct AA{T} <: GeneralStruct
vector::Vector{T}
car::Car
end
The basic idea is to test the correct parametrization of complex structs by accessing their attributes.
In order to do that, we define the necessary functions as:
function getvector(mystruct::S) where {S <: GeneralStruct}
mystruct.vector
end
function getcar(mystruct::S) where {S <: GeneralStruct}
mystruct.car
end
Instantiate our struct with different types
a = AA([1.,2.,3.], Volvo())
b = AA([1,2,3], Mazda())
Each one is parametrized according to its input data. So, lets check for type stability.
@code_warntype getvector(a)
@code_warntype getcar(a)
So there seems to be an issue with how we parametrized the car attributes.
Therefore, we should better work with a new structure that also parametrizes the singletons of type Car as follows:
struct AB{T, C <: Car} <: GeneralStruct
vector::Vector{T}
car::C
end
a = AB([1., 2., 3.], Volvo())
This new object has parametrized all the data objects inside {Float64, Volvo}
, so the compiler nows in advance what kind of objects to expect.
@code_warntype getcar(a)
Now everything seems to be working fine.
The next step is try to make a collection with these structs, i.e., a dictionary or tuples. Let’s see the difference.
aa = Dict{Symbol,T where T <: GeneralStruct}(:a=> a, :b=> b)
bb = (; :a => a, :b => b)
Dictionaries
in this case doesn’t seem to parametrize correctly these objects whereas for the NamedTuple
created this problem is not present. Let’s check this with an example.
First define a function that retrieves an element from it of type GeneralStruct
.
function getfroma(a::Dict)
a[:b]
end
function getfroma(a::NamedTuple)
a[end]
end
@code_warntype getfroma(aa)
@code_warntype getfroma(bb)
Clearly the dictionary doesn’t parametrize correctly the object inside, whereas for the named tuple it works correclty.
var s = "JavaScript syntax highlighting";
alert(s);
s = "Python syntax highlighting"
print s