More lessons learned: The person who keyed me in on the problem with
head also pointed out that using an immutable list for the accumulator in the
fold() could impact performance significantly. So, like any responsible programmer
, I ran my code through a profiler.
The results for larger lists was quite illuminating. For smaller lists (up to 6 elements in my tests), the recursive step wasn't even flagged as the biggest bottleneck. What got flagged instead was the initial creation of the lists themselves, that is, the call to
listOf(), especially the first few ones in a series of calls to
listOf() I had in my
main() function.
The recursive call did get flagged as the main bottleneck when I tried it with a larger list, 10 elements (3,628,800 permutations).
The version that used
fold(mutableListOf()) took 508ms at the recursive call, taking 53% of the entire run time.
I had to stop the version that used
fold(listOf()) { ... + acc } after 50+ seconds because it was getting ridiculous. I tried with just 9 elements (362,880 permutations) and it took the recursive part 3,398ms and 89% of the entire run time. The mutable list version with 9 elements took 70ms and 47% of the time at the recursive step, but again, the
listOf in
main() to create the original list was flagged as the main bottleneck, clocking in at 90ms and 60% of the time.
It looks like performance for the immutable version definitely degrades much faster (exponentially?) as the list size increases.
Based on this, I'm reverting to using a mutable accumulator for the
fold().