3 ms·
These are good strategies for speeding up Clojure code, and are great if you have a small handful of hotspots where performance really matter. However, if you c
by dwohnitmok 6y ago
These are good strategies for speeding up Clojure code, and are great if you have a small handful of hotspots where performance really matter. However, if you constantly find yourself resorting to these strategies and you're in a team environment, I would recommend just writing everything in Java and slapping a Clojure wrapper on top.
The main problem is that some of these optimizations are very brittle in combination with one another and require a good deal of care to maintain their effectiveness. A person unfamiliar with your codebase who just marches in and starts writing idiomatic Clojure can inadvertently deoptimize large swaths of your codebase.
This is a problem that afflicts a lot of languages that have a wide variance in performance between idiomatic-but-slow and idiomatic-but-fast (or close to idiomatic) variants of the same code. Haskell is another good example of this, which is perhaps even more extreme in that very fast Haskell code can look perfectly idiomatic, but an otherwise innocent-looking change can crash everything to the ground.
That variance is always going to exist to some degree in every language, but if you find that you need to always or almost always be on the latter side of that divide to meet your performance targets, maintenance and knowledge transfer is going to be a huge pain. You might want to consider rewriting it in a different language that shifts the variance further down field so that you're back on the easy side of that divide for most of your codebase.
- fulafel 6y agoThis is an argument worth considering, but on the other hand keeping track of performance regressions using CI is not hard and requires the team to master a new language that isn't the first choice for other code in the project.
- dwohnitmok 6y agoI disagree in the particular case of Clojure and Java (there are other places where I would agree, famously Jane Street gets by with staying in OCaml as much as possible and writing copious amounts of C-ish OCaml where necessary). > keeping track of performance regressions using CI is not hard It's actually kind of hard on the JVM. Again, if you have only a few hotspots then it's easy enough to set up some tests, but if you really need coverage over most of your codebase, it can get tricky, especially because these optimizations can combine in nonlocal ways so just exercising one function in one context doesn't guarantee the same performance in another. When taking into account warming up JIT compilation, benchmarks can become a real time suck. Criterium runs take a long time. You can't pop them like candy in the same way you can with unit tests, otherwise you can easily face hour+ CI runs. The usual way I've seen this work successfully is if you get lucky and your project has very few overall code paths that you can test with e.g. integration tests and you can catch essentially all perf regressions there. > requires the team to master a new language that isn't the first choice for other code in the project I think you really need to have a good grasp of Java to write Clojure well (or you'll develop it as you write more Clojure). Both because the ecosystem makes liberal use of Java libraries and because otherwise none of the stack traces or even the optimization decisions listed in this article will really make sense. Clojure doesn't do much to hide Java from you (which has its own set of pros and cons).
- fulafel 6y ago> I think you really need to have a good grasp of Java to write Clojure well (or you'll develop it as you write more Clojure). My experience is pretty much the opposite. Java programming experience is not needed. Of course you'll develop your understanding and experience of the JVM platform and some Java APIs as a user over time but that's still far from being comfortable writing Java code. I'll concede that optimizing with annotations is helped by Java experience, especially is it includes Java perf work.