# Deepcopy() of Dict has same mallocs as deepcopy() of Vector inside mutable Struct

**URL:** <https://discourse.julialang.org/t/deepcopy-of-dict-has-same-mallocs-as-deepcopy-of-vector-inside-mutable-struct/53420>\
**Category:** Performance\
**Tags:** deepcopy\
**Created:** [January 15, 2021, 11:37pm UTC](https://discourse.julialang.org/t/deepcopy-of-dict-has-same-mallocs-as-deepcopy-of-vector-inside-mutable-struct/53420 "2021-01-15T23:37:24Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![bsuwal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bsuwal/32/19577_2.png) [@bsuwal](https://discourse.julialang.org/u/bsuwal)\
**Post date:** [January 15, 2021, 11:37pm UTC](https://discourse.julialang.org/t/deepcopy-of-dict-has-same-mallocs-as-deepcopy-of-vector-inside-mutable-struct/53420/1 "2021-01-15T23:37:24Z")

</div>

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`

```julia
        - 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

```julia
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

```julia
@time deepcopy_n_times(struct_dict, n)
@time deepcopy_n_times(struct_vec, n)

```

I get:

```julia
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:

```julia
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)

```

---

<div class="post-metadata">

**Author:** ![Lilith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lilith/32/27492_2.png) [@Lilith](https://discourse.julialang.org/u/Lilith)\
**Post date:** [March 23, 2024, 11:03pm UTC](https://discourse.julialang.org/t/deepcopy-of-dict-has-same-mallocs-as-deepcopy-of-vector-inside-mutable-struct/53420/2 "2024-03-23T23:03:22Z")

</div>

Seems like a strange result fro --track-allocations. The `@time` results make more sense. Does the [allocation profiler](https://docs.julialang.org/en/v1/manual/profile/#allocation-profiler) give results consistent with `@time`?
