Improve performance
or opened this issue · 1 comments
As most users, I use linters and formatters mainly in my editor, but also to check or fix a larger code base at the command line or in workflows.
For both of those usages performance is a factor, so I've been trying to reduce cljfmt
start-up and run time.
- I've experimented with using
pmap
to process multiple files forfix
, and that sped up fixing a largeish directory by a factor of 2-3, so I think a--parallel
option would be useful, would you consider a PR for that feature? - the plugin to create a native image currently has a bug that prevents the
:jvm-opts
specified for it to be used (see taylorwood/lein-native-image#8), if those flags are used, then the executable is about 20% faster on my machine (with GraalVM CE or EE); I only mention this here as a heads up, as I hope the plugin will be fixed soon, but if that takes longer than expected it might be worth to use the workaround - a small performance improvement for native-image is not using
read-string
here: https://github.com/or/cljfmt/blob/da37b7aef08be99dbb8e2e8772d95308150d7adb/cljfmt/src/cljfmt/main.clj#L146, which is done to allow.clj
files for indents and aliases; a little surprisingly this doubles the size of the native-image executable and removing it improves performance by about 4-5% - I realize that's not huge, but would you consider a build flag that turns off .clj support?
The largest improvement is using GraalVM EE, which has nothing to do with cljfmt
, but it almost doubles the speed out of the box, and even there the jvm-opts
and clj-support removal have a noticeable impact. For the largest CLJS file in my project the current master took a median of 556ms to fix an already formatted file (with the various options I use), with the changes it's down to 443ms. With GraalVM EE this crumbles to 258ms.
These are all acceptable numbers, but I think it's worth optimizing this as much as possible, so it becomes unnoticeable when used in an on-save handler in the editor.
For reference:
version | GraalVM | size in MB | –help | check in ms | fix in ms | speed % | EE speed % |
---|---|---|---|---|---|---|---|
master | CE 22.1.0 Java 17 | 37 | 91 | 568 | 556 | 100 | |
jvm-opts | CE 22.1.0 Java 17 | 36 | 85 | 473 | 464 | 120 | |
jvm-opts, no-clj | CE 22.1.0 Java 17 | 17 | 80 | 451 | 443 | 126 | |
master | EE 22.1.0 Java 17 | 36 | 61 | 320 | 314 | 177 | 100 |
jvm-opts | EE 22.1.0 Java 17 | 37 | 56 | 277 | 267 | 208 | 118 |
jvm-opts, no-clj | EE 22.1.0 Java 17 | 19 | 54 | 265 | 258 | 216 | 122 |
I haven't tried a comparison with the leiningen plugin, but perhaps a section in the README on these options (lein, GraalVM CE, and EE) and how they compare could be useful for anyone wanting to adopt cljfmt
and having performance concerns.
Sure, I'll accept any well written PR that improves performance.