https://github.com/jgpc42/jmh-clojure-task
Convenience tools for jmh-clojure
https://github.com/jgpc42/jmh-clojure-task
Last synced: 4 months ago
JSON representation
Convenience tools for jmh-clojure
- Host: GitHub
- URL: https://github.com/jgpc42/jmh-clojure-task
- Owner: jgpc42
- License: epl-1.0
- Created: 2021-08-24T16:58:19.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2025-01-11T13:59:33.000Z (about 1 year ago)
- Last Synced: 2025-01-11T14:44:52.317Z (about 1 year ago)
- Language: Clojure
- Size: 31.3 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://clojars.org/jmh-clojure/task)
[][ci]
### Dependency and version information
Click to show
[Leiningen][lein]
``` clojure
[jmh-clojure/task "0.1.1"]
```
[tools.deps][deps]
```clojure
{jmh-clojure/task {:mvn/version "0.1.1"}}
```
[Maven](http://maven.apache.org)
``` xml
jmh-clojure
task
0.1.1
```
JDK versions 8 to 16 and Clojure versions 1.7 to 1.10 are currently [tested against][ci].
### What is it?
Various convenience utilities for [jmh-clojure][jmh-clj] intended to be used by higher-level tools. Note that while the examples below use `tools.deps`, this library can also be used via a [`Leiningen plugin`][lein-jmh], or standalone, as well.
### Usage
For `clj`, the recommend way to use this library is by adding an alias to your `deps.edn`. The following will be sufficient for most users:
```clojure
{#_...
:aliases
{:jmh {:extra-paths ["classes"]
:extra-deps {jmh-clojure/task {:mvn/version "0.1.1"}}
:ns-default jmh.task
:exec-fn jmh.task/run}}}
```
It's important to notice that the `"classes"` directory is added to the project paths. This is required for `jmh-clojure` since it generates `.class` files dynamically (written to `*compile-path*`, by default). We must add this output directory so it's available on the classpath when running.
By default, a `jmh.edn` file at the root of your project is used to configure the benchmark runner. Please see the [sample file][sample] for a complete guide. For example, the following runs all benchmarks, enables the standard JMH status log, and outputs pretty-printed benchmark result data:
```bash
$ mkdir -p classes
$ clj -X:jmh :format :pprint, :status true
```
> If you're new to the `-X` flag, it allows us to omit the Clojure map curly braces (`{}`) on the command line.
Notice again that we must manually create the `classes` directory before running. Ensuring the `*compile-path*` directory exists is not automated by `tools.deps` as it is with other tools like Leiningen.
### Available options
The optional map to `jmh.task/run` specifies the normal jmh-clojure run [options][run-doc]. The extra task options provided by this library include:
| Option | Description |
| ------------- | ---------------------------------------------- |
| `:exclude` | keys to remove from each benchmark result map. |
| `:file` | read the given file(s) instead of `jmh.edn`. |
| `:format` | print results in the given format(s). |
| `:only` | keys to select from each benchmark result map. |
| `:output` | specify the location to write the results. |
| `:pprint` | equivalent to `:format :pprint`. |
| `:progress` | display progress data while running. |
| `:sort` | key(s) to order the results by. |
Please run `clj -X:jmh help` for more information on the available options. Note that some formats (e.g., `:table`) exclude some result information due to space considerations. See the previously mentioned help for details.
The available JMH profilers may be listed with: `clj -X:jmh profilers`.
### Uberjar example
Along with integrating with the Clojure project tool of your choice, you can also create a standalone jar file. This is useful if you intend to run benchmarks on a different machine than your development one and want to package everything up so you don't have to re-create the project build environment. The `jmh.main` namespace is designed to be used as the jar entry point.
For Clojure tools, we'll use the [`uberdeps`][udeps] library to create the jar. In the root of a hypothetical project:
```bash
mkdir -p classes uberdeps
echo '{:deps {uberdeps/uberdeps {:mvn/version "1.0.4"}}}' > uberdeps/deps.edn
clj -Ajmh -M -e "(compile 'jmh.main)"
cd uberdeps
clj -M -m uberdeps.uberjar --aliases jmh --deps-file ../deps.edn --main-class jmh.main --target ../target/jmh.jar
mkdir classes
cp ../jmh.edn .
java -cp classes:../target/jmh.jar jmh.main '{:type :quick}'
```
Note again that even when running as an uberjar, we still need to create the `classes` directory beforehand to enable the dynamic compilation. Additionally, we copy `jmh.edn` to the working directory so it can be found by the runner. This file can also be packaged as a jar resource so this step is optional. Running with `-Dfile.encoding=UTF-8` is also advisable depending on your platform due to the unicode characters JMH can output.
The procedure for other tools should be similarly straightforward.
### More information
Please see the [`jmh-clojure`][jmh-clj] project for everything else about jmh-clojure.
### Running the tests
```bash
lein test
```
Or, `lein test-all` for all supported Clojure versions.
### License
Copyright © 2017-2025 Justin Conklin
Distributed under the Eclipse Public License, the same as Clojure.
[ci]: https://github.com/jgpc42/jmh-clojure-task/blob/master/.github/workflows/test.yml
[deps]: https://github.com/clojure/tools.deps.alpha
[jmh-clj]: https://github.com/jgpc42/jmh-clojure
[lein]: http://github.com/technomancy/leiningen
[lein-jmh]: https://github.com/jgpc42/lein-jmh
[run-doc]: https://jgpc42.github.io/jmh-clojure/doc/jmh.core.html#var-run
[sample]: https://github.com/jgpc42/jmh-clojure/blob/master/resources/sample.jmh.edn
[udeps]: https://github.com/tonsky/uberdeps