Hello,
I am trying to understand what affects the performance of code in Julia.
Please see below for three functions combo_with_max_sum
, combo_with_max_sum_2
and combo_with_max_sum_3
.
-
I would have expected version 2 to have less allocations than version 1 because version 1 creates a new dictionary, whereas the latter does not. However, version 2 has far more allocations and is slower than version1. Why is this? Is this because the function is accessing struct fields?
-
Version 3 is like version 2, except I pass struct fields instead of passing in the struct. This has zero allocations and is the fastest.
My question is: is it bad to pass structs to functions and then work with the fields in the function?
Thank you.
The code with benchmarks:
import OrderedCollections as OC
import BenchmarkTools as BT
struct MyStruct
alternatives
avmap
end
function init_mystruct()
alternatives = [Symbol("A$(i)") for i = 1:10]
@show alternatives
avmap = OC.OrderedDict{Tuple{Symbol, Symbol}, Tuple{Float64, Float64}}()
for a1 in alternatives
for a2 in alternatives
avmap[(a1, a2)] = (rand(), rand())
end
end
MyStruct(alternatives, avmap)
end
function combo_with_max_sum(avmap)
agg_avmap = OC.OrderedDict(combo => sum(vals) for (combo, vals) in avmap)
findmax(agg_avmap)[2]
end
function combo_with_max_sum_2(mys)
retv = (mys.alternatives[1], mys.alternatives[1])
maxval = sum(mys.avmap[retv])
for (combo, val) in mys.avmap
s = sum(val)
if s >= maxval
maxval = s
retv = combo
end
end
return retv
end
function combo_with_max_sum_3(alternatives, avmap)
retv = (alternatives[1], alternatives[1])
maxval = sum(avmap[retv])
for (combo, val) in avmap
s = sum(val)
if s >= maxval
maxval = s
retv = combo
end
end
return retv
end
function pqmain()
mystruct = init_mystruct()
alts = mystruct.alternatives
avmap = mystruct.avmap
return (mystruct, alts, avmap)
end
julia> include("src/Temp/PerfQues.jl")
pqmain (generic function with 1 method)
julia> (mys, alts, avmap) = pqmain();
alternatives = [:A1, :A2, :A3, :A4, :A5, :A6, :A7, :A8, :A9, :A10]
julia> using BenchmarkTools
julia> @btime combo_with_max_sum($avmap)
2.607 ÎĽs (14 allocations: 7.39 KiB)
(:A2, :A5)
julia> @btime combo_with_max_sum_2($mys)
17.500 ÎĽs (1103 allocations: 39.14 KiB)
(:A2, :A5)
julia> @btime combo_with_max_sum_3($alts, $avmap)
63.988 ns (0 allocations: 0 bytes)
(:A2, :A5)