Open jdashton opened 2 years ago
And, to clarify, I first tried the Rust solution with 49 threads (one from each of Player 2's first round of rolls), but that tended to be about 8 ms slower than your straight-forward approach. When I moved to instead start 7 threads, one from each of Player 1's first round of rolls, that's when this solution became faster. Creating threads is costly, so this makes sense to me. Also, having 7 threads contending for the mutex should be much better than having 49 threads contending for it.
And . . . I just checked the numbers when run with --release
, and the straight-forward solution takes only one third the time of the recursive caching approach.
:: day21
generator: 1.136µs
part1: (444ns, 518418)
part2: (2.328331ms, 116741133558209)
:: day26
generator: 842ns
part1: (426ns, 518418)
part2: (7.983128ms, 116741133558209)
Optimizations rock!
Simon, thank you SO MUCH for sharing your code for 2021. It has been really eye-opening!
I've learned so much from the approach you take; I'm still trying to see problems more as you see them. I re-implemented your Day 21 solution in my own Ruby code, and was delighted that it can get under 600 ms. I then re-worked it to use various combinations of multi-threading, recursion and caching, and the fastest time I saw was close to 250 ms. That is for a recursive, multi-threaded, caching solution that runs in 49 threads when my system is otherwise very unoccupied. It's fun to see all 16 cores of my i9 at least show a blip.
You also inspired me to try applying the same techniques to your Rust code. I finally found a combination that consistently turns-in slightly faster times. I called it Day 26, to make it easy to run beside your original Day 21 code.
Here is the relevant code:
With your experience, you may see further optimizations that I can't see yet.
Thank you again for all the motivation!