I havea set of functions that I want to use on some data. Currently, I am storing these functions in a global array to be able to index them.
const global _rot01(x)::Tuple{Int64, Int64, Int64} = ( x[1], x[2], x[3])
const global _rot02(x)::Tuple{Int64, Int64, Int64} = ( x[2], x[3], x[1])
...
const global _rot24(x)::Tuple{Int64, Int64, Int64} = (-x[1], -x[3], -x[2])
const global Rotations = [
_rot01,
...
_rot24
]
However, I wish to optimize this, as I have heard that global values should be avoided. A switch statement would allow me to efficiently select the right function, but these are not available. Is this vector of functions the only way to do this? How efficient is this? Also, should I replace the functions with 'real' function definitions?
First, you do not need to write:
const global _rot01(x)::Tuple{Int64, Int64, Int64} = ( x[1], x[2], x[3])
It is enough to define functions like this:
_rot01(x)::Tuple{Int64, Int64, Int64} = ( x[1], x[2], x[3])
Functions are const by default. And what you write are real function definitions. Also you do not need to write ::Tuple{Int64, Int64, Int64}
(unless you know you need to to force conversion of data), it is enough to just write:
_rot01(x) = ( x[1], x[2], x[3])
Unless x
is some strange data structure (e.g. vector of Any
) Julia will do detection of return type of the function automatically.
Second in:
const global Rotations = [
_rot01,
...
_rot24
]
you do not need to write global
(I understand you are defining Rotations
in global scope).
Instead I think a nice thing to write would be:
const global Rotations = (; _rot01, ... _rot24)
This defines you a Rotations
as a named tuple, you can then access it as:
Rotations[1]
or
Rotations._rot01
to get the first function and it will be efficient.
If you do not like it then doing a tuple:
const global Rotations = (_rot01, ... _rot24)
is also OK (but you then only have access by index not by name).
Now why defining:
const Rotations = [
_rot01,
...
_rot24
]
is bad. The reason is that then the element type of this vector will be Function
which means that your code will not be type stable as Function
is an abstract type (as opposed to Tuple
or NamedTuple
that specialize their field types). And type unable code leads to performance degradation.
Finally,
You only need to define Rotations
as const
if you want to access it from global scope. But if you want to pass it to functions it is fully OK to just define it as a normal variable and pass as a function parameter and things will be fast.
I know that I touched a lot of things in the answer. If something requires further clarification please comment.