Since this article focuses on the performance of GraalVM, and the performance when using Graal as a JIT compiler, this article does not touch on one of the features of GraalVM, such as native image and multiple languages.
It is a VM equipped with Graal, the latest JIT compiler written in Java. According to the GraalVM Official Document, Graal has the following features.
Graal itself is implemented in java, which can significantly speed up Java programs with powerful optimizations such as partial escape analysis not possible with standard JIT compilers.
How fast it will actually be will be described later.
By the way, if it is troublesome to change the VM, it seems that you can change only the JIT compiler to Graal by adding the following options. However, please note that according to Reference, it can only be used with JDK10 or later.
-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler
It has the following architecture. Compared to the standard JVM, the C2 part has been replaced by the Graal compiler. The Graal and JVMCI parts are implemented in Java.
JVMCI A compiler implemented in Java that can be used in the JVM as a dynamic compiler.
https://openjdk.java.net/jeps/243
Follow the instructions in the Official Documentation. For macOS, here
A more detailed speed comparison can be found in this article.
Run a program that spits out the top 10 word types contained in the 275Mb GraalTest.txt
.
$ ll
total 65368
-rw-r--r-- 1 kinsho staff 202B 5 31 14:04 FibTest.scala
-rw-r--r-- 1 kinsho staff 1.9K 5 31 17:13 GraalTest.scala
-rw-r--r-- 1 kinsho staff 275M 5 31 16:54 GraalTest.txt
drwxr-xr-x 4 kinsho staff 128B 5 31 14:28 project
drwxr-xr-x 5 kinsho staff 160B 5 31 14:35 target
Use GraalVM installed above as a VM.
$ java -version
openjdk version "1.8.0_252"
OpenJDK Runtime Environment (build 1.8.0_252-b09)
OpenJDK 64-Bit Server VM GraalVM CE 20.1.0 (build 25.252-b09-jvmci-20.1-b02, mixed mode)
Below, the executable program
GraalTest.scala
import java.io.File
import scala.annotation.tailrec
import scala.io.BufferedSource
object GraalTest extends App {
val fileName: String = "GraalTest.txt"
val encode: String = "UTF-8"
val source: BufferedSource = scala.io.Source.fromFile(fileName, encode)
val lines: Iterator[String] = source.getLines()
val sortedTextList = lines.toList.mkString(" ").split(" ").sorted.toList
val value = createMap(sortedTextList)
val top10Words = value.toList.sortBy(_._2).reverse.take(10)
def createMap(wordList: List[String]): Map[String, Long] = {
@tailrec
def loop(list: List[String], acc: Map[String, Long]): Map[String, Long] = {
wordList match {
case head :: tail if acc.isEmpty => {
loop(tail, acc + (head -> 1L))
}
case head :: tail => {
acc.get(head) match {
case Some(value) => {
loop(tail, acc.updated(head, value + 1L))
}
case None => {
loop(tail, acc + (head -> 1L))
}
}
}
case head :: Nil => {
acc.get(head) match {
case Some(value) => {
acc.updated(head, value + 1L)
}
case None => {
acc + (head -> 1L)
}
}
}
}
}
loop(wordList, Map.empty[String, Long])
}
}
For comparison, let's run the program using OpenJDK's standard JIT compiler.
If you specify -XX: -Use JVMCI Compiler
, you can use the standard JIT compiler of OpenJDK.
.jvmopts
-XX:-UseJVMCICompiler
-Xmx8G
Run
$ /usr/bin/time sbt run GraalTest.scala
Then, the following result is obtained.
JVM results
[info] running GraalTest
List((the,3297996), (and,2198664), (of,2198664), (you,1648998), (a,1648998), (in,1648998), (about,1099332), (always,1099332), (with,1099332), (how,1099332))
[success] Total time: 64 s (01:04), completed 2020/06/04 0:38:37
85.31 real 479.11 user 8.89 sys
Try running the above program on GraalVM.
.jvmopts
-Xmx8G
Run
$ /usr/bin/time sbt run GraalTest.scala
Then, the following result is obtained.
GraalVM results
[info] running GraalTest
List((the,3297996), (and,2198664), (of,2198664), (you,1648998), (a,1648998), (in,1648998), (about,1099332), (always,1099332), (with,1099332), (how,1099332))
[success] Total time: 54 s, completed 2020/06/04 0:40:02
75.29 real 333.95 user 9.23 sys
By using GraalVM, you can see that it is 10s faster. This is much faster !!!!!
↓ Codes used for performance measurement https://github.com/kinshotomoya/loginfrastructure/tree/master/jitCompiler
If you can use Graal instead of the current JIT compiler, you should use it.
Next time, I will summarize another feature of GraalVM, native-image.
Recommended Posts