Hello,
This started as a fun exploration, I donβt have a specific usecase for it but maybe somebody else will.
This is a very small package that introduces a permutedims!(array, perm) variant that permutes an array reusing the same underlaying memory buffer without needing auxiliary buffers/allocations.
It needs to known array sizes and permutation tuple at compile time for best performance.
using InplacePermutations
A = rand(8, 6, 2, 2)
Aorig = copy(A) # keep a pristine reference for comparison
B = InplacePermutations.permutedims!(A, (2, 4, 1, 3)) # mutates A in place
B == permutedims(Aorig, (2, 4, 1, 3)) # true
size(B) # (6, 2, 8, 2)
Baseline Base.permutedims! with a (36,24) array
BenchmarkTools.Trial: 10000 samples with 259 evaluations per sample.
Range (min β¦ max): 297.297 ns β¦ 692.085 ns β GC (min β¦ max): 0.00% β¦ 0.00%
Time (median): 297.938 ns β GC (median): 0.00%
Time (mean Β± Ο): 302.942 ns Β± 15.778 ns β GC (mean Β± Ο): 0.00% Β± 0.00%
βββ β ββββ β
βββββββββββββββββββββ
βββ
β
β
β
β
β
ββ
β
β
β
β
β
β
βββ
β
βββββββ
β
ββ
ββ
β
β
β
β
ββ
ββ β
297 ns Histogram: log(frequency) by time 377 ns <
Memory estimate: 0 bytes, allocs estimate: 0.
Same array with array size and permutation known at compile time
BenchmarkTools.Trial: 10000 samples with 671 evaluations per sample.
Range (min β¦ max): 187.841 ns β¦ 325.633 ns β GC (min β¦ max): 0.00% β¦ 0.00%
Time (median): 188.462 ns β GC (median): 0.00%
Time (mean Β± Ο): 191.987 ns Β± 8.242 ns β GC (mean Β± Ο): 0.00% Β± 0.00%
βββββββββββ β β β
ββββββββββββββββββββββββββββββββββββββββββββββββ
β
ββ
β
ββ
ββ
β
β
β
β
β β
188 ns Histogram: log(frequency) by time 226 ns <
Memory estimate: 0 bytes, allocs estimate: 0.
There are some caveats:
- Works best on small ish arrays
- Can be compilation heavy with big arrays (tunable trade-off between compilation time and speed)
- New sizes/perm combinations will generate a new function everytime.
More details in the repo.
PS.: currently being registered. Not married to the name, if you have opinions let me know!