JuliaMath / Combinatorics.jl

A combinatorics library for Julia
http://juliamath.github.io/Combinatorics.jl/dev/
Other
214 stars 58 forks source link

`permutations` is less efficient than `multiset_permutations` #151

Open FedericoStra opened 8 months ago

FedericoStra commented 8 months ago

I noticed that permutations is much less efficient than the more general multiset_permutations when they are both applied to a collection with unique elements:

julia> collect(permutations(1:8)) == collect(multiset_permutations(1:8, 8))
true

julia> @benchmark permutations(1:8) |> collect |> length
BenchmarkTools.Trial: 8 samples with 1 evaluation.
 Range (min … max):  614.237 ms … 656.276 ms  ┊ GC (min … max): 0.00% … 0.00%
 Time  (median):     626.957 ms               ┊ GC (median):    0.00%
 Time  (mean ± σ):   632.481 ms ±  15.159 ms  ┊ GC (mean ± σ):  0.04% ± 0.12%

  █        █     ██   █          █                         █  █
  █▁▁▁▁▁▁▁▁█▁▁▁▁▁██▁▁▁█▁▁▁▁▁▁▁▁▁▁█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█▁▁█ ▁
  614 ms           Histogram: frequency by time          656 ms <

 Memory estimate: 6.46 MiB, allocs estimate: 80643.

julia> @benchmark multiset_permutations(1:8, 8) |> collect |> length
BenchmarkTools.Trial: 1080 samples with 1 evaluation.
 Range (min … max):  3.769 ms … 10.225 ms  ┊ GC (min … max):  0.00% … 28.42%
 Time  (median):     4.049 ms              ┊ GC (median):     0.00%
 Time  (mean ± σ):   4.624 ms ±  1.031 ms  ┊ GC (mean ± σ):  11.09% ± 14.36%

   ▄█▆▅▄▃▁        ▁       ▁▁    ▁
  █████████▆▇▆▁▆▆▇█▇▇█▇████████▇█▇▇█▇▇▆█████▇▆▇█▅▅▄▁▄▆▄▅▁▁▅▆ █
  3.77 ms      Histogram: log(frequency) by time     7.77 ms <

 Memory estimate: 11.38 MiB, allocs estimate: 120991.

I haven't investigated the reason behind this, but I believe that it is indicative of the fact that the implementation of permutations is not optimal.