GraalVM demos: Native images for faster startup

This is a sample application to demonstrate GraalVM capabilities for creating native images.

Prerequisites

Preparation

Download or clone the repository and navigate into the native-list-dir directory:

git clone https://github.com/graalvm/graalvm-demos
cd graalvm-demos/native-list-dir

There are two Java classes, but we will start by building ListDir.java for the purposes of this demo. You can manually execute javac ListDir.java, there is also a build.sh script included for your convenience.

Note that you can use any JDK for compiling the Java classes, however we refer to javac from GraalVM in the build script to simplify the prerequisites and not to depend on another JDK installed.

Export the GraalVM home directory as the $GRAALVM_HOME and add $GRAALVM_HOME/bin to the path, using a command-line shell for Linux:

export GRAALVM_HOME=/home/${current_user}/path/to/graalvm

and for Mac OS:

export GRAALVM_HOME=/Users/${current_user}/path/to/graalvm/Contents/Home

Note that your paths are likely to be different depending on the download location.

Then execute:

./build.sh

The build.sh script creates a native image from the Java class. Let us look at it in more detail:

$GRAALVM_HOME/bin/native-image ListDir

The native-image utility is a part of GraalVM. It is used to compile applications ahead-of-time for faster starup and lower general overhead at runtime.

After executing the native-image command, check the directory, it should have produced an executable file listdir.

Running the application

To run the application, you need to either execute the ListDir class, as a normal Java application using java, or, since we have a native image prepared, run that directly.

The run.sh file, executes both, and times them with the time utility.

time java ListDir $1
time ./listdir $1

To make it more interesting, pass it to a parent directory: ./run.sh .. (.. - is the parent of the current directory, the one containing all the demos).

Approximately, the following output should be produced:

+ java ListDir ..
Walking path: ..
Total: 141 files, total size = 14448801 bytes

real	0m0.320s
user	0m0.379s
sys	0m0.070s
+ ./listDir ..
Walking path: ..
Total: 141 files, total size = 14448801 bytes

real	0m0.030s
user	0m0.005s
sys	0m0.011s

The performance gain of the native version is largely due to the faster startup.

ExtListDir class

You can also experiment with a more sophisticated ExtListDir example, which uses Java/JavaScript polyglot capabilities.

To compile that class you need to add graal-sdk.jar on the classpath:

$GRAALVM_HOME/bin/javac -cp $GRAALVM_HOME/jre/lib/boot/graal-sdk.jar ExtListDir.java

Building the native image command is similar to the one above, but, since we want to use JavaScript, we need to inform the native-image utility about it by passing the --language:js option. Note that it takes a bit more time because it needs to include the JavaScript support.

$GRAALVM_HOME/bin/native-image --language:js ExtListDir

The execution is the same as in the previous example:

time java ExtListDir $1
time ./extlistdir $1