When trying to solve an alphametics problem with permutations from Combinatorics.jl, I came across something I don’t understand about the performance.
If I introduce permutations to the namespace via using Combinatorics: permutations, the performance on large problems is terribly slow compared to when I copy and paste the source code directly from Combinatorics.jl/src/permutations.jl
An example algorithm for solving an alphametics puzzle:
function solve(puzzle)
terms = reverse.(split(replace(puzzle, r"[+=]"=> ""), " "))
leading, letters = Set(last.(terms)), union(Set(terms)...)
for perm in permutations(0:9, length(letters))
solution = Dict(zip(letters, perm))
all(lead-> !iszero(solution[lead]), leading) && trial(solution, terms) && return solution
end
end
function trial(dict, terms)
sum(sum(dict[t]*10^(n-1) for (n,t) in enumerate(term)) for term in terms[1:end-1]) == sum(dict[t]*10^(n-1) for (n,t) in enumerate(last(terms)))
end
Shows something like:
julia> using Combinatorics: permutations;
julia> @time solve("AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE");
90.300626 seconds (27.97 M allocations: 1.320 GiB, 0.17% gc time, 0.09% compilation time)
However, when I cut and paste the file from source (after restarting the kernel), I see something like:
julia> @time solve("AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE");
1.310297 seconds (37.97 M allocations: 2.005 GiB, 14.97% gc time, 7.91% compilation time)
This becomes much worse with a larger example, so I’m wondering why this happens (and potentially where). Since there is a significant difference not only in execution time, but also an inverse one with memory allocation, I would assume there is some sort of optimization happening somewhere which is prioritizing space over time, but I am ignorant as to what that process could be or if there is some way to get around it. For my case, low run time is of more importance, but I would like to be able to use the package (via using Combinatorics) rather than explicitly copying in all the source code.
Final note: I’ve noticed this happening both my local environment and in a Docker image run on AWS.