julia> struct Tree
left::Tree
right::Tree
Tree() = new()
Tree(l, r) = new(l, r)
end
julia> a = Tree()
Tree(#undef, #undef)
julia> for i=1:20
a = Tree(a, a)
end
julia> using Serialization
julia> serialize("s.dat", a)
The resulting file has size 10MB. It does not resolve the objectid to save space I guess.
Is there some trick to circumvent this issue?
Good point, they are probably the same thing. My temporary solution is keeping a dictionary of objects, and then dump this dictionary. Wondering if it can be made more elegant.
The actual storage is 20 x (the object size of Tree type). Because we only create this many objects. They are conceptually big, but in the computer memory, they are just 20 linked addresses with a lot memory sharing.
julia> a = Tree()
Tree(#undef, #undef)
julia> for i=1:21
a = Tree(a, a)
end
julia> serialize("s.dat", a)
shell> ls s.dat -l
-rw-rw-r-- 1 leo leo 20971537 Mar 15 19:55 s.dat
julia> a = Tree()
Tree(#undef, #undef)
julia> for i=1:20
a = Tree(a, a)
end
julia> serialize("s.dat", a)
shell> ls s.dat -l
-rw-rw-r-- 1 leo leo 10485777 Mar 15 19:55 s.dat
julia> objectid(a.left)
0xb6935cdf82ed648e
julia> objectid(a.right)
0xb6935cdf82ed648e
So, we have
The size is exponential increasing as the depth,
The object id of left and right branch is the same.
I think immutable types do not always copy, otherwise the following code would blow up my memory:
julia> struct Tree
left::Tree
right::Tree
Tree() = new()
Tree(l, r) = new(l, r)
end
julia> a = Tree()
Tree(#undef, #undef)
julia> for i=1:200
a = Tree(a, a)
end
But I do tried your suggestion of making it mutable, and the serialized file is reasonablly small.
Semantically they copy, though in this case the compiler can optimise things by using references instead (probably because you have possibly undefined fields), which is why your example doesn’t blow up.
julia> mutable struct Tree
left::Tree
right::Tree
Tree() = new()
Tree(l, r) = new(l, r)
end
julia> a = Tree()
Tree(#undef, #undef)
julia> for i=1:20
a = Tree(a, a)
end
julia> using Serialization
julia> serialize("s.dat", a)
julia> stat("s.dat")
StatStruct for "s.dat"
size: 167 bytes