Hi I have a question on defining a function that returns an immutable type.
To be specific, let me define two immutable types:
immutable test1 a::Int64 b::Int64 end
immutable test2 a::Int64 b::Bool end
t1 = test1(1,1) and
t2 = test2(1, true), I want to change
1 to, say,
2. But since both
test2 are immutable type, I cannot change the value in the usual way.
So I wrote a function as follows:
using Base.Cartesian @generated function change_immutable(t::Any, name::Symbol, val::Any) names = fieldnames(t) len = length(names) quote @ncall $len typeof(t) i-> getindex($names, i) == name ? val : getfield(t, i) end end
The first argument takes any (immutable) type, the second argument takes the symbol in the type where the corresponding value needs to be changed to
val, the third argument.
change_immutable(t1, :a, 2) gives
test1(2, 1) and
change_immutable(t2, :a, 2) gives
test2(2, true). I know that
t2 haven’t changed, but that is okay and this function does what I want to implement.
But the problem is that
change_immutable function sometimes allocates additional memory. Using the following function:
function memory_test(t) for i=1:1000 change_immutable(t, :a, i) end end
@time memory_test(t1) returns
0.000013 seconds (4 allocations: 160 bytes) but
@time memory_test(t2) returns
0.000067 seconds (1.49 k allocations: 39.047 KiB), which allocates additional memory compared to the first case.
Do you know how to construct a function that does the same thing as
change_immutable yet allocates less memory even in
test2 immutable type?