I need to define a function that fixes the value of another functionβs argument. One way is the following:
using InvertedIndices, PreallocationTools, BenchmarkTools
function construct_fixed_f(g, n, val, cache)
new_f = @inline (x, p) -> begin
cache2 = get_tmp(cache, x)
cache2[Not(n)] .= x
cache2[n] = val
return g(cache2, p)
end
end
_f = (x, p) -> x[1] * x[2] * x[3] + p[1] * p[2]
_p = [2.0, 3.0]
_n = 2
_val = 2.0
_x = rand(3)
cache = DiffCache(_x)
fixed_f = construct_fixed_f(_f, _n, _val, cache) # _f([x[1], 2.0, x[3]], p)
But this seems to be very slow. A comparison of evaluating the returned function vs. the original function:
test_x_fix =[2.7, 3.7]
test_x = [2.7, _val, 3.7]
@benchmark $_f($test_x, $_p)
@benchmark $fixed_f($test_x_fix, $_p)
julia> @benchmark $_f($test_x, $_p)
BenchmarkTools.Trial: 10000 samples with 1000 evaluations.
Range (min β¦ max): 2.300 ns β¦ 25.700 ns β GC (min β¦ max): 0.00% β¦ 0.00%
Time (median): 2.400 ns β GC (median): 0.00%
Time (mean Β± Ο): 2.445 ns Β± 0.513 ns β GC (mean Β± Ο): 0.00% Β± 0.00%
β β β β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
2.3 ns Histogram: log(frequency) by time 3.9 ns <
Memory estimate: 0 bytes, allocs estimate: 0.
julia> @benchmark $fixed_f($test_x_fix, $_p)
BenchmarkTools.Trial: 10000 samples with 197 evaluations.
Range (min β¦ max): 452.792 ns β¦ 62.085 ΞΌs β GC (min β¦ max): 0.00% β¦ 98.73%
Time (median): 470.051 ns β GC (median): 0.00%
Time (mean Β± Ο): 593.130 ns Β± 1.571 ΞΌs β GC (mean Β± Ο): 6.93% Β± 2.61%
ββ
βββ ββ
β
β
ββ β
βββββββββββββββββββββββββββββ
ββ
β
β
β
βββ
β
β
ββ
β
β
βββ
βββ
β
β
ββ
βββ
β
βββ β
453 ns Histogram: log(frequency) by time 1.38 ΞΌs <
Memory estimate: 496 bytes, allocs estimate: 15.
Why the big difference? Whatβs the best way to do this?