Because of habits from previous languages, I think, I was wanting to pass around an object (t) that would handle incoming data (“f”) based on parameters (in the example “d”). That was doing a lot of allocation. Based on my experimentation, it seems the pattern could be instead to pass around an indicator type and have method that accepts both the data (“x”) and the parameter (“d”). I did a fair bit of googling but couldn’t find a great explainer to fix my confusion. Care to share a link or advice?
struct MyType
f
end
function make_mytype(d::Float64)
return MyType(f::Float64->d+f)
end
function process_x(t::MyType, x::Float64)
a = t.f(x)
return nothing
end
myt = make_mytype(2.0)
process_x(myt, 1.0)
struct MyType2
end
function handle_mytype2(x::Float64, t::MyType2, d::Float64)
return d + x
end
function process_x2(x, t, d)
a = handle_mytype2(x, t, d)
return nothing
end
myt2 = MyType2()
process_x2(1.0, myt2, 2.0)
Profile.clear_malloc_data()
@time process_x(myt, 1.0)
@time process_x2(1.0, myt2, 2.0)
With output
0.000003 seconds (85 allocations: 6.123 KiB)
0.000002 seconds (4 allocations: 160 bytes)
and Coverage analyze_malloc
julia> analyze_malloc(".")
3-element Array{Coverage.MallocInfo,1}:
Coverage.MallocInfo(0, "./test.jl.mem", 11)
Coverage.MallocInfo(16, "./test.jl.mem", 10)
Coverage.MallocInfo(28716, "./test.jl.mem", 6)