Table of Contents
When executing a short-lived CLI application written in Java, a huge portion of the runtime is wasted on booting the JVM.
To fix this issue, nailgun can be used: Nailgun is a client, protocol, and server for running Java programs from the command line without incurring the JVM startup overhead. Programs run in the server (which is implemented in Java), and are triggered by the client (written in C), which handles all I/O.
To use nailgun to increase the performance of pgpainless-cli
, the first thing you need is a Java 8 installation.
This is because nailgun uses features from Java 8, which were removed in later releases.
Futher, you need to compile PGPainless using Java 8 to get a compatible jar file.
$ JAVA_HOME=$JAVA8_HOME gradle assemble
$ ls pgpainless-cli/build/libs/pgpainless-cli-XYZ-all.jar
Start the nailgun server
Simply execute the nailgun-server.jar on the Java 8 JVM:
$ $JAVA8_HOME/bin/java -jar nailgun-server.jar
Next, load the freshly built pgpainless-cli-XYZ-all.jar:
$ ng ng-cp /path/to/pgpainless-cli-XYZ-all.jar
Execute PGPainlessCLI calls
The syntax for calling pgpainless-cli only changes a little bit. Here is an example without and with using nailgun:
$ # WITHOUT nailgun
$ java -jar pgpainless-cli-XYZ-all.jar generate-key "Alice <alice@example.org>"
$ # WITH nailgun
$ ng org.pgpainless.cli.PGPainlessCLI generate-key "Alice <alice@example.org>"
As you can see, you now need to provide the name of the main class.
Results
On my machine, comparing the performance shows a drastic improvement!
$ time (repeat 100 {java -jar pgpainless-cli-1.5.1-all.jar generate-key > /dev/null;})
( repeat 100; do; java -jar pgpainless-cli-1.5.1-all.jar generate-key > ; done 167,06s user 9,14s system 216% cpu 1:21,42 total
$ # vs.
$ time (repeat 100 {ng org.pgpainless.cli.PGPainlessCLI generate-key > /dev/null;})
( repeat 100; do; ng org.pgpainless.cli.PGPainlessCLI generate-key > /dev/nul) 0,21s user 0,99s system 20% cpu 5,914 total