julia lang - Efficient-yet-terse way to add all the arrays in a composite type? -


i came 2 ways add arrays in pair of composite types. first way (add_structs_1) takes 4 seconds run , second way (add_structs_2) takes 0.15 seconds. second way requires lot more code...i have explicitly mention each field in composite type. there way efficiency of add_structs_2, without explicitly listing each field?

type samplestruct     a::vector{float64}     k::matrix{float64}     e_axis::vector{float64}     e_dev::vector{float64}     e_scale::vector{float64} end  function add_structs_1(tgt::samplestruct, src::samplestruct)     n in names(samplestruct)         in 1:length(tgt.(n))             tgt.(n)[i] += src.(n)[i]         end     end end  function add_structs_2(tgt::samplestruct, src::samplestruct)     in 1:length(tgt.a)         tgt.a[i] += src.a[i]     end      in 1:length(tgt.k)         tgt.k[i] += src.k[i]     end      in 1:length(tgt.e_axis)         tgt.e_axis[i] += src.e_axis[i]     end      in 1:length(tgt.e_dev)         tgt.e_dev[i] += src.e_dev[i]     end      in 1:length(tgt.e_scale)         tgt.e_scale[i] += src.e_scale[i]     end end  function time_add_structs(f::function)     src = samplestruct(ones(3), ones(3,3), [1.], [1.], [1.])     tgt = samplestruct(ones(3), ones(3,3), [1.], [1.], [1.])      @time in 1:1000000         f(tgt, src)     end end  time_add_structs(add_structs_1) time_add_structs(add_structs_1)  time_add_structs(add_structs_2) time_add_structs(add_structs_2)  time_add_structs(add_structs_3) time_add_structs(add_structs_3) 

a more julian approach add_structs_1 make inner loop separate function, allows compiler specialize function on each type in samplestruct , gives quite speedup.

by profiling code visible time execute names(samplestruct) quite significant, , should done in each iteration of benchmark, making global constant time gained , function looks like:

function add_array(a::abstractarray,b::abstractarray)     in 1:length(a)         a[i] += b[i]     end end const names_in_struct = names(samplestruct) function add_structs_3(tgt::samplestruct, src::samplestruct)     n in names_in_struct         add_array(tgt.(n),src.(n))     end end 

the function within factor of 4 of add_structs_2

the metaprogramming approach more complicated gives same performance add_structs_2

ex = any[] n in names(samplestruct)     t = expr(:.,:tgt, quotenode(n))     s = expr(:.,:src, quotenode(n))     e=quote         in 1:length($t)             $t[i] += $s[i]         end     end     push!(ex,e) end eval(quote function add_structs_4(tgt::samplestruct, src::samplestruct)       $(expr(:block,ex...))     end  end) 

Comments