This all depends on the context. You can time and check allocated memory yourself using among others @time
, BenchmarkTools.jl’s @btime
, @benchmark
, or Chairmark.jl’s @b
:
Method definitions
using BenchmarkTools
function duplicate_preallocated()
array = [1,2,3,4,4,4,5]
dup = zeros(Int, length(array))
counter = 1
for i = 1 : (length(array)-1)
for j = 1 : i
if array[j] == array[i+1]
dup[counter] = array[j]
counter += 1
end
end
end
return dup
end
function duplicate_push() # cf. hz-xiaxz, Eliassj
array = [1,2,3,4,4,4,5]
dup = Int[] # could use sizehint! for potentially slightly better performance
for i = 1 : (length(array)-1)
for j = 1 : i
if array[j] == array[i+1]
push!(dup, array[j])
end
end
end
return dup
end
function duplicate_comprehension() # cf. bertschi
array = [1,2,3,4,4,4,5]
return [array[j]
for i in 1:(length(array)-1)
for j in 1:i
if array[j] == array[i+1]]
end
function duplicate_dict()
array = [1,2,3,4,4,4,5]
dup = Dict{Int, Int}()
counter = 1
for i = 1 : (length(array)-1)
for j = 1 : i
if array[j] == array[i+1]
dup[counter] = array[j]
counter += 1
end
end
end
return dup
end
julia> @btime duplicate_preallocated()
47.172 ns (4 allocations: 224 bytes)
7-element Vector{Int64}:
4
4
4
0
0
0
0
julia> @btime duplicate_push()
47.730 ns (3 allocations: 208 bytes)
3-element Vector{Int64}:
4
4
4
julia> @btime duplicate_comprehension()
73.975 ns (5 allocations: 272 bytes)
3-element Vector{Int64}:
4
4
4
julia> @btime duplicate_dict()
109.903 ns (6 allocations: 560 bytes)
Dict{Int64, Int64} with 3 entries:
2 => 4
3 => 4
1 => 4
If I were to phrase these results as the Dict
approach being more than twice as slow as the push!
version, you might conclude that it is much less efficient. If you needed to run this function many times for different (small) input array
s, this would certainly be a valid conclusion.
Alternatively, you might say that using Dict
s here is only some 60 ns slower, which is completely negligible. This conclusion would be equally valid, if you would only need to run this function once.