Most efficient way to unpack array into variables?

When optimising some complicated model, I find two things are important:

  1. Readability (I want to use correct variable names, not array_of_parameters[index_required])

  2. Speed (the function may be called many thousands of times)

The model function parameters argument needs to be a vector (in NLopt.jl which I am currently using in my package).

A generalized example of what I currently do is the following:

var1, var2, var3 = array_of_params

But I am wondering if there are faster ways of doing this? Or if there is just a known best solution that I have missed?

I have read the following:

https://groups.google.com/forum/#!topic/julia-users/IQS2mT1ITwU

But it’s still not clear to me how to do this with minimum overhead. Any suggestions would be greatly appreciated!

julia> arr = [1,2,3]
julia> @btime a,b,c = $arr
  2.027 ns (0 allocations: 0 bytes)
3-element Array{Int64,1}:
 1
 2
 3

Your current solution seems really fast already. Do you really think that it will be a bottleneck?

As for the question you linked to, that concerns programatically generating variable identifiers, which I think is a bad idea that makes code less readable, not more.

1 Like

How many variables does your code have, roughly? And is every variable a scalar, or is there more structure to your data? There may be a few different options depending on the particulars of your problem.

1 Like

At present it varies from 2 - 6. Larger models might be included in future which have more parameters (~10 to 20). Every variable is a scalar, usually Float64.

Looking @DNF’s benchmark, I wonder if I’m spending energy optimizing in the wrong place in this instance. However, I’m still very interested for future reference as it will definitely be useful to know for the type of work I’m doing.

Maybe something like https://github.com/rafaqz/Flatten.jl would be helpful in your case? It makes it easier to unpack a vector, not into a list of variables but into a structure with named fields.

2 Likes

The style you adopted, direct assignment from a single sequentially ordered datatype into distinct, appropriately named, variables is the win: it combines obviousness, clarity for others, and performance.

The current internal setting for the number of args a function may process quickly, without falling back on other machinery, has been increased from ~14 to ~30 or more. Your explicit assignments are unlikely to find that sort of limit.

2 Likes

Thanks that makes sense.

If possible, could you post any links to other discourse posts / github issues / documentation that you think would help me understand what’s going on ‘under the hood’ that introduces this ~30 args limit?

Its in the source code and not something you want to alter. I don’t recall which, there is some github issue.