@jordanterrell: Yes, yes, yes, PROFILE to find perf bottlenecks! I jumped straight from the art code to the opposite extreme of in-place mutation, but did not profile the art code, just assumed that spinning up closures in State was the culprit.
And 100% agree that the provability and reliability of monadic functional code is worth it in many (most?) circumstances. On the perf critical path, profile and compromise as needed, focusing on implementation innards.