Two scripts that look identical at first glance but one is 60X faster than the other.
If I didn’t make a mistake in taking the measurements, where is the substantial difference?
why 60X faster?
julia> uu=vcat(repeat(uu,2))
12-element Vector{Vector{Tuple{Tuple{Int64, Int64}, Tuple{Int64, Int64}}}}:
[((1, 2), (3, -2)), ((1, 3), (3, -3))]
[((1, -1), (2, 1))]
[((1, 1), (2, -1)), ((1, -1), (2, 1))]
[((2, -2), (4, 2)), ((2, -3), (4, 3))]
[((3, 1), (4, -1)), ((3, 4), (4, -4))]
[((3, 1), (4, -1)), ((3, 2), (4, -2)), ((3, 3), (4, -3))]
[((1, 2), (3, -2)), ((1, 3), (3, -3))]
[((1, -1), (2, 1))]
[((1, 1), (2, -1)), ((1, -1), (2, 1))]
[((2, -2), (4, 2)), ((2, -3), (4, 3))]
[((3, 1), (4, -1)), ((3, 4), (4, -4))]
[((3, 1), (4, -1)), ((3, 2), (4, -2)), ((3, 3), (4, -3))]
julia> using .Iterators: flatten
julia> using BenchmarkTools
julia> function mergetuple1(uu)
res=Vector{NTuple{length(uu),eltype(uu[1])}}()
N=maximum(first, flatten(flatten(uu)))
v=zeros(Int,N)
for u in Iterators.product(uu...)
for pp in u
for (f,l) in pp
v[f]+=l
end
end
all(iszero,v) && push!(res, u)
v.=0
end
res
end
mergetuple1 (generic function with 1 method)
julia> function mergetuple2(uu)
function m(u,v)
# for (f,l) in flatten(u)
# v[f]+=l
# end # 650 us
for pp in u
for (f,l) in pp
v[f]+=l
end
end # 500 us
all(iszero,v)
end
res=Vector{NTuple{length(uu),eltype(uu[1])}}()
N=maximum(first, flatten(flatten(uu)))
v=zeros(Int,N)
for u in Iterators.product(uu...)
m(u,v) && push!(res, u)
v.=0
end
res
end
mergetuple2 (generic function with 1 method)
julia> @btime mergetuple1(uu)
31.329 ms (366344 allocations: 16.18 MiB)
1-element Vector{NTuple{12, Tuple{Tuple{Int64, Int64}, Tuple{Int64, Int64}}}}:
(((1, 2), (3, -2)), ((1, -1), (2, 1)), ((1, -1), (2, 1)), ((2, -2), (4, 2)), ((3, 1), (4, -1)), ((3, 1), (4, -1)), ((1, 2), (3, -2)), ((1, -1), (2, 1)), ((1, -1), (2, 1)), ((2, -2), (4, 2)), ((3, 1), (4, -1)), ((3, 1), (4, -1)))
julia> @btime mergetuple2(uu)
513.600 μs (6920 allocations: 3.94 MiB)
1-element Vector{NTuple{12, Tuple{Tuple{Int64, Int64}, Tuple{Int64, Int64}}}}:
(((1, 2), (3, -2)), ((1, -1), (2, 1)), ((1, -1), (2, 1)), ((2, -2), (4, 2)), ((3, 1), (4, -1)), ((3, 1), (4, -1)), ((1, 2), (3, -2)), ((1, -1), (2, 1)), ((1, -1), (2, 1)), ((2, -2), (4, 2)), ((3, 1), (4, -1)), ((3, 1), (4, -1)))