My apologies and thanks for pointing this out - I’m sure I ran into an issue with this before, where I had to solve an optimization problem for millions of rows in a DataFrame, where each row held parameters for the optimization problem. Initially I redefined the objective function for each row with the new parameters (which were all the same type), which was very slow, and following a discussion on Slack (which is now in the memory hole of course) I moved to putting things in containers like above which was a lot faster.
I can’t reproduce this now though:
using Optim
function main()
rosenbrock(x, a, b) = (a - x[1])^2 + 100.0 * b*(x[2] - x[1]^2)^2
a = [1.0]
b = [1.0]
my_obj(x, a=a[1], b=b[1]) = rosenbrock(x, a, b)
println("\n")
println("Parameters in container")
println("First optimization")
@time optimize(my_obj, zeros(2), BFGS()).minimizer
println("Second optimization")
@time optimize(my_obj, zeros(2), BFGS()).minimizer
println("Changing parameter value")
a = [2.0]
println("First optimization with new parameter")
@time optimize(my_obj, zeros(2), BFGS()).minimizer
println("Second optimization with new parameter")
@time optimize(my_obj, zeros(2), BFGS()).minimizer
println("\nRedefine objective function for each parameter change")
my_obj2(x) = rosenbrock(x, 1.0, 1.0)
println("First optimization")
@time optimize(my_obj2, zeros(2), BFGS()).minimizer
println("Second optimization")
@time optimize(my_obj2, zeros(2), BFGS()).minimizer
println("Changing parameter value")
my_obj2(x) = rosenbrock(x, 1.0, 2.0)
println("First optimization with new parameter")
@time optimize(my_obj, zeros(2), BFGS())
println("Second optimization with new parameter")
@time optimize(my_obj, zeros(2), BFGS())
end
main()
Shows that even when redefining the objective with new parameters, there’s no compilation cost:
Parameters in container
First optimization
1.215204 seconds (1.61 M allocations: 85.647 MiB, 2.55% gc time)
Second optimization
0.000133 seconds (1.67 k allocations: 44.562 KiB)
Changing parameter value
First optimization with new parameter
0.000180 seconds (2.89 k allocations: 75.438 KiB)
Second optimization with new parameter
0.000160 seconds (2.89 k allocations: 75.438 KiB)
Redefine objective function for each parameter change
First optimization
0.084680 seconds (100.97 k allocations: 5.498 MiB)
Second optimization
0.000175 seconds (918 allocations: 39.281 KiB)
Changing parameter value
First optimization with new parameter
0.000244 seconds (2.89 k allocations: 75.438 KiB)
Second optimization with new parameter
0.000159 seconds (2.89 k allocations: 75.438 KiB)