I think you got me right. I was about to create a contrived but clear example, but then I figured I might as well just put the actual code here, and test it!
Code
Nested:
function nested(retina, distance, aperture, morphz)
layers, rc, ous, nodalz, focallengths = createobj(morphz)
r = Ray()
function θ2signal(θ)
l = Light(distance, aperture, rc, θ, nodalz)
function getsignal(b)
ous[retina].medium.signal.photoreceptor = 0.0
try
l(r, b[1], b[2])
raytrace!(r, ous)
catch ex
ex isa RayTraceEllipsoids.DeadRay || throw(ex)
end
ous[retina].medium.signal.photoreceptor
end
s, _ = hcubature(getsignal, [0, 0], [1, 0.5], initdiv=10, maxevals=10^4)
s
end
s0 = θ2signal(0)
fun(θ) = (θ2signal(θ) - s0/2)^2
res = optimize(fun, 1e-4, 0.45)
Optim.minimizer(res)
end
Not Nested:
function getsignal(b, ous, retina, l, r)
ous[retina].medium.signal.photoreceptor = 0.0
try
l(r, b[1], b[2])
raytrace!(r, ous)
catch ex
ex isa RayTraceEllipsoids.DeadRay || throw(ex)
end
ous[retina].medium.signal.photoreceptor
end
function θ2signal(θ, distance, aperture, rc, nodalz, ous, retina, r)
l = Light(distance, aperture, rc, θ, nodalz)
s, _ = hcubature(b -> getsignal(b, ous, retina, l, r), [0, 0], [1, 0.5], initdiv=10, maxevals=10^4)
s
end
function notnested(retina, distance, aperture, morphz)
layers, rc, ous, nodalz, focallengths = createobj(morphz)
r = Ray()
s0 = θ2signal(0, distance, aperture, rc, nodalz, ous, retina, r)
res = optimize(θ -> θ2signal(θ, distance, aperture, rc, nodalz, ous, retina, r), 1e-4, 0.45)
Optim.minimizer(res)
end
Benchmarks
Nested:
BenchmarkTools.Trial:
memory estimate: 105.94 MiB
allocs estimate: 4444955
--------------
minimum time: 2.583 s (0.59% GC)
median time: 2.584 s (0.54% GC)
mean time: 2.584 s (0.54% GC)
maximum time: 2.584 s (0.48% GC)
--------------
samples: 2
evals/sample: 1
Not nested:
BenchmarkTools.Trial:
memory estimate: 16.72 MiB
allocs estimate: 752272
--------------
minimum time: 2.836 s (0.10% GC)
median time: 2.837 s (0.05% GC)
mean time: 2.837 s (0.05% GC)
maximum time: 2.839 s (0.00% GC)
--------------
samples: 2
evals/sample: 1
Conclusions
So, not nested is ~10% slower but takes ~5 times less memory.