I recently needed to optimize the speed of some Clojure code. After investigating, I identified that a huge number of exceptions were being thrown and handling these was slowing down the process.
The code throwing the exceptions was parsing strings into Joda-Time DateTime objects using the clj-time library.
The code was calling clj-time.coerce/from-string which calls clj-time.format/parse. format/parse
iterates through up to approximately 50 formatters in an attempt to parse whatever string you pass it. If one of these formatters doesn’t parse the string, it throws an exception which format/parse
catches and ignores before attempting the next formatter.
This was pretty wasteful. This was especially wasteful in the code I was working in since it only needed to handle two different date formats.
Luckily, Joda-Time has a way to build a formatter that handles multiple formats and clj-time provides access to it. Below is code that creates a formatter that handles two different formats.
1 2 3 4 5 6 7 8 9 10 11 |
|
And below are some examples of using it in the repl.
1 2 3 4 5 6 7 8 |
|
Looking back at that code, it seems pretty straightforward. I’ll admit that it took me and my pair a while to figure out how to do this using clj-time
. I ended up looking at Joda-Time’s documentation and implemented this using Java interop before I cracked how to use clj-time.format/formatter
to do the same thing.