I had a struct that had a Dict
as one of its fields. I deepcopy
the struct objects a lot, and that was the bottleneck in the program. I then realized that I could replace the Dict
with a Vector, which I know has a smaller memory footprint (based on Base.summarysize()
). However, after changing the Dict
to a Vector
the memory allocated is still the same, even though the number of allocations decreased. Could someone help explain this?
Code, Memory size (in bytes) and num allocations below:
The following is the output .mem
file from julia -- track-allocation=user filename.jl
- using Profile
-
- small_n = 10
- n = 100000
-
- mutable struct MyStructWithDict
0 d::Dict{Int, Int}
- i::Int
- end
-
- mutable struct MyStructWithVector
0 d::Vector{Int}
- i::Int
- end
-
- function deepcopy_n_times(obj::MyStructWithDict, n::Int)
0 for i in 1:n
36800000 deepcopy(obj)
- end
- end
-
- function deepcopy_n_times(obj::MyStructWithVector, n::Int)
0 for i in 1:n
36800000 deepcopy(obj)
- end
- end
-
- example_dict = Dict{Int, Int}(2 => 2)
- struct_dict = MyStructWithDict(example_dict, 1)
- example_vec = Vector{Int}([2])
- struct_vec = MyStructWithVector(example_vec, 1)
-
- println("Size of Dict: ", Base.summarysize(struct_dict.d))
- println("Size of Int: ", Base.summarysize(struct_dict.i))
- println("Size of DictStruct: ", Base.summarysize(struct_dict))
- println()
- println("Size of Vector: ", Base.summarysize(struct_vec.d))
- println("Size of Int: ", Base.summarysize(struct_vec.i))
- println("Size of VectorStruct: ", Base.summarysize(struct_vec))
-
- deepcopy_n_times(struct_dict, small_n)
- deepcopy_n_times(struct_vec, small_n)
-
- Profile.clear_malloc_data()
-
- deepcopy_n_times(struct_dict, n)
- deepcopy_n_times(struct_vec, n)
The output from the above print statements is
Size of Dict: 456
Size of Int: 8
Size of DictStruct: 472
Size of Vector: 48
Size of Int: 8
Size of VectorStruct: 64
When I replace the last two lines above with
@time deepcopy_n_times(struct_dict, n)
@time deepcopy_n_times(struct_vec, n)
I get:
0.106812 seconds (700.00 k allocations: 96.130 MiB, 7.34% gc time)
0.082474 seconds (400.00 k allocations: 47.302 MiB, 5.97% gc time)
which shows that the number of allocations has decreased, but the total memory hasn’t?
I’m pasting the same code as above in case you don’t want to deal with the output of the mem file:
using Profile
small_n = 10
n = 100000
mutable struct MyStructWithDict
d::Dict{Int, Int}
i::Int
end
mutable struct MyStructWithVector
d::Vector{Int}
i::Int
end
function deepcopy_n_times(obj::MyStructWithDict, n::Int)
for i in 1:n
deepcopy(obj)
end
end
function deepcopy_n_times(obj::MyStructWithVector, n::Int)
for i in 1:n
deepcopy(obj)
end
end
example_dict = Dict{Int, Int}(2 => 2)
struct_dict = MyStructWithDict(example_dict, 1)
example_vec = Vector{Int}([2])
struct_vec = MyStructWithVector(example_vec, 1)
println("Size of Dict: ", Base.summarysize(struct_dict.d))
println("Size of Int: ", Base.summarysize(struct_dict.i))
println("Size of DictStruct: ", Base.summarysize(struct_dict))
println()
println("Size of Vector: ", Base.summarysize(struct_vec.d))
println("Size of Int: ", Base.summarysize(struct_vec.i))
println("Size of VectorStruct: ", Base.summarysize(struct_vec))
deepcopy_n_times(struct_dict, small_n)
deepcopy_n_times(struct_vec, small_n)
Profile.clear_malloc_data()
deepcopy_n_times(struct_dict, n)
deepcopy_n_times(struct_vec, n)