Good to hear I did not add too much confusion: Since you appear to have understood the broad strokes, I will go a bit more into detail (sorry, I had to over-simplify to get my point across):
Re: type stable
Technically, I believe “type stable” simply means Julia can figure out the exact concrete type of a function’s return value knowing only the types of its inputs parameters.
So… technically, you are not supposed to say “generates a type stable vector”… I think the more correct statement is that a particular Vector
constructor (a function) was type stable. Again: this is true when Julia can determine the type of the result simply by looking at the types of the constructor’s input parameters.
In reality: type stability is only a subset of the problem (albeit one that people have difficulty with). What you really should be asking is: “is Julia able to figure out which (type-sensitive) method to call given the types of your function’s input parameters”. This is especially true when you start executing long, complex loops.
Now for your questions:
Non-parametrized : generates type a stable vector since all elements are of type Layer
.
Technically, that is what I said in order to keep close to your wording. Indeed: it is very likely that Julia “calls” a type-stable constructor when you create the non-parameterized Vector{Layer}
.
However, what is more important is how efficiently Julia will then use this vector as opposed to the vector made up of LayerP{:MATERIAL}
(the parameterized version). What I was saying here is that both solutions are pretty much of the same efficiency… that is unless you have a vector where all the layers are of type LayerP{:MATERIALX}
. In that case, Julia does not have to generate an implicit “if” statement to dispatch on the LayerP
object type - because it knows the exact type of all the elements (ie, they are all layers that use MATERIALX
).
I will refrain to answer your question about non-parameterized types because it will not help here. Feel free to re-ask once you have read this post.
Case 1: type stable, but if-statement is called.
myfun([LayerAl, LayerVac])
Again, that is what I said in an attempt to keep close to your wording.
Technically, since I don’t know what dosomething()
returns… so I cannot say if this myfun()
method is type stable… (Remember, type stability is only a subset of the issue).
What I can say is that in this non-parameterized version of Layers
, the vector:
lstack = [LayerAl, LayerVac]
Is a fully concrete Vector{Layer}
. That means that whenever we call a function on any of those Layer
objects themselves, Julia knows exactly which function to call (does not have to do an implicit “if” statement yet…). For example, if you just need to sum up the thicknesses, you can call:
thickness(v::Vector{Layer}) = sum([l.thickness for l in v])
Julia will be very efficient because it does not need an implicit “if” statement anywhere.
However, when you finally run an operation that depends on the the material itself, that’s when Julia starts to add in implicit “if” statements. For example:
effective_permittivity(v::Vector{Layer}) = #Something that depends on .material
Sadly, very little can be done to improve Julia’s calculations on Vector
s when you are structuring the solution the way you are. There might be alternatives out there, but your solution would likely be significantly different. I personally find your type hierarchy to be relatively good at the moment.
The main reason why you will not see an improvement by parameterizing your Layer
object is the following:
- In most cases (not all), efficiencies gained by parameterizing a type are observed when you have to execute the same code over a large number of that exact type (ie a large
Vector
of that type). In these cases, Julia will be compiling type-specific code that will often be faster.
- You could in theory parameterize
Layer
for different Material
s in order to gain computational efficiency. But this added efficiency will mostly be observed when you execute code on a Vector
of Layer{MaterialX}
(all the parameter types are the same). Since there is no real interest in solving problems where a stack is made up of all of the same parameter (or material, in this case), I don’t see a reason for this “optimization” (added complexity).