Don’t give up so soon! ![]()
The following change makes funvar! just as fast again:
args = let j = j
ntuple(i -> A[i][j], N)
end
σ[i] = f(Δx, args...)
in context:
function funvar!(σ::AbstractVector{<:Real},
x::Vector{Float64},
xl::Vector{Float64},
f::F,
A::Vararg{Vector{Float64},N}) where {F <: Function, N}
L = length(xl)
jstart = 1
for i = 1:length(x)
j = jstart
while (j <= L) && abs(x[i] - xl[j]) > 0.1
j += 1
end
if j <= L
jstart = j
while (j <= L) && abs(x[i] - xl[j]) < 0.1
Δx = x[i] - xl[j]
args = let j = j
ntuple(i -> A[i][j], N)
end
σ[i] = f(Δx, args...)
j += 1
end
end
end
end
The let j = j thing is necessary to avoid the weird performance issue with boxed variables in closures ( Performance Tips · The Julia Language)
Results:
julia> @btime funvar!($σ, $x, $xl, $test, $a, $b)
890.985 μs (0 allocations: 0 bytes)
julia> @btime funvar!($σ, $x, $xl, $test, $a, $b, $c)
938.801 μs (0 allocations: 0 bytes)
julia> @btime fun2!($σ, $x, $xl, $a, $b)
851.805 μs (0 allocations: 0 bytes)
julia> @btime fun3!($σ, $x, $xl, $a, $b, $c)
911.132 μs (0 allocations: 0 bytes)