Notes on how to use GraalVM profile-guided optimizations

As a brief note today, I found that GraalVM was actually making one of my Scala/Java/JVM applications slower, so with the help of Thomas Wuerthinger at Oracle, I learned a little bit about how to use the GraalVM profile-guided optimizations.

The short story is:

  • You need to install the GraalVM Enterprise Edition
  • Then you need to install the Oracle GraalVM Enterprise Edition Native Image Early Adopter with this command:
gu install --local-file my/path/to/my/native_image_download.jar

You can find both of those downloads at this URL.

After downloading those, create a native image as usual, but add the --pgo-instrument flag. Then run your application one time. Running your application creates a file named default.iprof. My command looked like this:

$ native-image --pgo-instrument -cp $SCALA_HOME/lib/scala-library.jar:FIND5.jar JavaNioFiles$delayedInit$body

That created a native image/executable named javaniofiles, and I ran it once.

Now create your native image a second time, this time with the --pgo profile.iprof flag. This second image should run significantly faster than the first image. I actually had a problem with that flag, as it had this error:

$ native-image --pgo default.iprof -cp $SCALA_HOME/lib/scala-library.jar:FIND5.jar JavaNioFiles$delayedInit$body
Build on Server(pid: 25373, port: 58567)
[JavaNioFiles:25373]    classlist:   3,364.67 ms
Error: Main entry point class 'default.iprof' not found.
Error: Use -H:+ReportExceptionStackTraces to print stacktrace of underlying exception
Error: Image build request failed with exit status 1

After reading the native-image --help docs I saw that you can run --pgo by itself, so I ran this command to create my second native executable:

$ native-image --pgo -cp $SCALA_HOME/lib/scala-library.jar:FIND5.jar JavaNioFiles$delayedInit$body

That created a new native image named javaniofiles (I renamed the first image before creating this one), and I ran it. The results were:

  • First native image: Took 74 seconds to run
  • Second native image: Took 56 seconds to run

Unfortunately in this specific case, running my JAR file with java -jar is actually faster than GraalVM, but hopefully the Graal team will be able to fix that, as my other tests have shown Graal to usually be significantly faster than java.