-
Notifications
You must be signed in to change notification settings - Fork 63
Performance update for permutations.jl #205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Update docstrings
Update for string comparison in `derangements`
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #205 +/- ##
==========================================
+ Coverage 97.17% 97.19% +0.02%
==========================================
Files 8 8
Lines 813 857 +44
==========================================
+ Hits 790 833 +43
- Misses 23 24 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Delete non-mutating `nextpermutation()`
Provide a derangement-specific implementation. Improving performance and providing further functionality.
|
I noticed that Some benefits of the new implementation:
BenchmarkingUnique set elementsCurrent implementation ( BenchmarkTools.Trial: 6 samples with 1 evaluation per sample.
Range (min … max): 475.889 ms … 1.359 s ┊ GC (min … max): 0.00% … 58.50%
Time (median): 1.009 s ┊ GC (median): 35.18%
Time (mean ± σ): 976.497 ms ± 295.074 ms ┊ GC (mean ± σ): 41.24% ± 21.38%
█ █ █ ██ █
█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█▁█▁▁▁▁▁▁▁▁▁▁██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█ ▁
476 ms Histogram: frequency by time 1.36 s <
Memory estimate: 1.16 GiB, allocs estimate: 19479014.New BenchmarkTools.Trial: 21 samples with 1 evaluation per sample.
Range (min … max): 131.592 ms … 551.025 ms ┊ GC (min … max): 0.00% … 62.50%
Time (median): 223.156 ms ┊ GC (median): 30.68%
Time (mean ± σ): 239.835 ms ± 100.070 ms ┊ GC (mean ± σ): 36.27% ± 21.40%
█▁█ ▁▁▁ █ █▁▁ ▁▁▁ ▁ ▁ ▁ ▁
███▁▁▁▁███▁█▁███▁▁███▁▁▁▁▁▁█▁▁▁▁▁█▁▁▁█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█ ▁
132 ms Histogram: frequency by time 551 ms <
Memory estimate: 218.85 MiB, allocs estimate: 2669983.Multiset elementsCurrent implementation ( BenchmarkTools.Trial: 63 samples with 1 evaluation per sample.
Range (min … max): 40.422 ms … 154.164 ms ┊ GC (min … max): 0.00% … 43.45%
Time (median): 75.977 ms ┊ GC (median): 25.91%
Time (mean ± σ): 80.700 ms ± 26.078 ms ┊ GC (mean ± σ): 24.51% ± 18.12%
█ ▁ ▁▁ ▁ ▄▁ ▁▁█ ▁ ▁ ▁ ▁▁▁ ▁
█▁▁▆█▆▁▆██▁█▁▆██▆▆▆▁▆███▆▁▆█▆▁▆█▆▁▆▆▆█▁▆███▁▁▆▁▆▁▆▁▆▆▁▁█▁▁▁▆ ▁
40.4 ms Histogram: frequency by time 133 ms <
Memory estimate: 142.82 MiB, allocs estimate: 2352076.New BenchmarkTools.Trial: 581 samples with 1 evaluation per sample.
Range (min … max): 5.055 ms … 65.012 ms ┊ GC (min … max): 0.00% … 81.06%
Time (median): 7.474 ms ┊ GC (median): 0.00%
Time (mean ± σ): 8.576 ms ± 5.002 ms ┊ GC (mean ± σ): 14.50% ± 17.52%
█▇▃▂▁ ▄▂▂▂▃▅▃▁
███████████████▇█▇▇█▆▇▇▇▆▇▇▆▇▅▄▆▁▄▁▅▁▆▁▁▁▁▁▄▄▅▄▆▄▁▁▄▄▁▁▁▄▄ ▇
5.06 ms Histogram: log(frequency) by time 27.2 ms <
Memory estimate: 13.37 MiB, allocs estimate: 168113. |
Iteration has been streamlined a bit more and some comments have been added to help with future maintenance.
|
Note: I've changed the three argument If it is meant to be exported, I believe it would need a docstring which explains how to construct |
This update contains improvements to the performance of
permutations.jl, keeping the underlying algorithm (nextpermutation()) in place (see Issue #204 for various benchmarks, with the benchmarking after the first post directly relevant to this implementation). The main strategy was to move potential overhead away from the performance critical methods ofnextpermutationanditerateto the constructors by standardizing input. One step involves separatingPermutationsfromMultiSetPermutationsby reverting to a previous version of theiteratemethod forPermutations(resulting in a large performance boost).Special attention was paid to reducing the number of allocations made by both
permutations()andmultiset_permutations(). To this end, one of the larger changes involves now modifying thestatein place during iteration (while the data in the structs remains unchanged). I can't currently see this as an issue since the algorithm is serial and can't be parallelized.In total, these modifications see a cut in allocations to 1/3 and 1/2 their current numbers for
permutations()andmultiset_permutations(), respectively, and bring their performance into line with Heap's Permutation Algorithm.Other notes:
mutlitset_permutations()andpermutations()now have the same performance on collections with unique elements (wherev.1.1.0hasmultiset_permutations()outperformingpermutations()).dataandmalways being aVector{T}whereTis the element type of the input.Vectors,Multidimensional Arrays,Sparse ArraysandOffset Arrays(i.e. coveringLinearIndex,CartesianIndexand offset indices).permutations()is now type safe (in line withmultiset_permutations()), always returning aPermutationstype.multiset_permutations(m, t)is now linear (vs the currentHeap's Algorithm used in performance comparisons
Note: Below is an implementation of Heap's algorithm which I used to compare performance. It was written to be comparable in structure to
nextpermutation()used in this update, but it's not actually correct forpermlen < length(data), since it always produces all permutations (i.e. there are potential duplicates).