I am pleased to announce Stringer, a library for fast string concatenation. Stringer is designed (with tradeoffs) to complement Clojure’s string concat operations.
Stringer’s API contains several macros (so they can not be used as functions) - notably strcat and strfmt that are used frequently. strcat is the Java equivalent of string concatenation + operator. In Java, when you write (“foo” + 42 + “bar”) the Java compiler generates in-line bytecode using java.lang.StringBuilder to concatenate the tokens. strfmt expects the format string (with limited specifier support) to be a literal and applies string interpolation to generate the formatted string much faster than clojure.core/format. The perf benchmark code is included in the repo.
We have used Stringer in production for over 3 years at SAP Concur with only one issue noticed/fixed over 2 years ago. It is usually hard to troubleshoot and optimize the long tail of latency; however, using Stringer has led to overall perf improvements in several composite use cases.
I’m curious as to how much faster Stringer is, compared to standard Clojure methods, like str and string/join. If you have any benchmarks, that would be interesting!
In the included benchmarks, the Stringer version gets faster and faster as you concatenate more and more small tokens. In my raw benchmarks stringer.core/strcat has turned out to be “up to 20 times” faster than clojure.core/str in various use cases. However, I would suggest to use your (realistic) project use cases in the benchmarks. YMMV
Disclaimer: A benchmark may not represent absolute perf gains in your app; however, the relative difference under high concurrency is more likely to be closer to the perf gains in production.