[Vorheriger Artikel](https://qiita.com/kinshotomoya/items/39a821dd6a6a52202c0a#%E5%AE%9F%E9%9A%9B%E3%81%AB%E4%BD%BF%E3%81%A3 % E3% 81% A6% E3% 81% BF% E3% 82% 8B) und der Geschwindigkeitsvergleich zwischen GraalVm und Standard-JVM wurde durchgeführt.
Da jedoch die Kompilierungszeit, die Aufwärmzeit und die reine Ausführungszeit gemischt und gemessen wurden, war es nicht möglich, einen reinen Geschwindigkeitsvergleich von Graal selbst durchzuführen.
Dieses Mal möchte ich die Geschwindigkeit von Graal von GraalVM und C2-Compiler von Standard-JVM vergleichen.
Daher unterscheiden wir zwischen Kompilierung (Generierung von Klassendateien), Aufwärmen und reiner Ausführungszeit und vergleichen die reine Ausführungszeit.
Generieren Sie bei der Ausführung mit sbt vor der Ausführung eine Mischklassendatei und messen Sie dann.
$ sbt compile
$ sbt run
Wie ich in diesem Artikel geschrieben habe, führt die JVM zuerst die Klassendatei auf dem Interprinter aus (erwärmt sie) und sammelt die für die Kompilierung erforderlichen Informationen. Der JIT-Compiler dient zum Kompilieren der Zielmethode.
** Um die reine Ausführungsgeschwindigkeit des Graal- oder C2-Compilers zu messen, müssen Sie die Zielmethode aufwärmen-> die Geschwindigkeit nach der Kompilierung messen. ** **.
Laut diesem Buch beträgt der Schwellenwert für den Wechsel vom Interprinter des JIT-Compilers zum JIT-Compiler das 8000-fache. Mit anderen Worten, wenn Sie eine Methode 8000 Mal oder öfter ausführen (aufwärmen), wird die Methode vom JIT-Compiler kompiliert, sodass Sie die Geschwindigkeit des kompilierten Codes messen können.
Das letzte Mal wurde die Messung mit dem Befehl / usr / bin / time
durchgeführt.
Da es jedoch nicht möglich ist, einen reinen Geschwindigkeitsvergleich durchzuführen, wird JMH verwendet, um genaue Werte zu erhalten.
Es gibt sbt library, also habe ich es benutzt.
Ein Programm, das englische Sätze aus einer Textdatei liest und die 10 am häufigsten verwendeten Wörter ausspuckt.
├── resources
│ └── GraalTest.txt
└── scala
└── graal
└── Performance.scala
Textdatei. Ich habe einen passenden englischen Satz mitgebracht.
Graal.txt
When people talk about Japan, they would always think about how innovative and technological this country gets! Or how pretty and neat the country is! Last but not the least, fashion, Cosplay and hype beast were always a big thing in the city of Japan. Coming to Japan with the intention of tourism would have been a great experience. Different culture. You can find a lot of unique things they sell in Japan! But as you live in Japan, you interact with the locals and everything doesn’t seem the way you thought of Japan.
Die Größe beträgt 525B.
$ ll
-rw-r--r-- 1 kinsho staff 525B 6 14 10:18 GraalTest.txt
In der JMH-Bibliothek können Messoptionen mit Anmerkungen angegeben werden. Es wurde wie folgt eingestellt.
** Aufwärmzahl ** 10000 Mal für die Zielmethode einmal ausführen. Wie oben erwähnt, wird die Zielmethode vom JIT-Compiler kompiliert, wenn die Anzahl der Ausführungen 8000 überschreitet. Erwärmen Sie sich daher vorerst 10000 Mal.
** Anzahl der Hinrichtungen ** Die Zielmethode wird 10000 mal 30 mal ausgeführt. Das offizielle Dokument besagt, dass Sie realistische Zahlen erhalten, wenn Sie von 10 auf 20 iterieren.
Performance.scala
package graal
import java.util.concurrent.TimeUnit
import org.openjdk.jmh.annotations._
import scala.annotation.tailrec
import scala.io.BufferedSource
//Geben Sie die Anzahl der Gabeln an
//Der Standardwert ist 5
@Fork(1)
@Warmup(iterations = 1, batchSize = 10000)
@Measurement(iterations = 30, batchSize = 10000)
//Messen Sie die Ausführungszeit pro Ausführung
@BenchmarkMode(Array(Mode.SingleShotTime))
//Maßeinheit ist ms
@OutputTimeUnit(TimeUnit.MILLISECONDS)
class GraalTest {
//Zielen Sie auf diese Methode ab
@Benchmark
def run = {
val fileName: String = "GraalTest.txt"
val encode: String = "UTF-8"
val source: BufferedSource = scala.io.Source.fromResource(fileName)
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)
}
private def createMap(wordList: List[String]): Map[String, Long] = {
@tailrec
def loop(list: List[String], acc: Map[String, Long]): Map[String, Long] = {
list 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)
}
}
}
case Nil => acc
}
}
loop(wordList, Map.empty[String, Long])
}
}
Zuerst kompilieren
sbt:jitCompiler> jmh:compile
[info] Compiling 3 Scala sources to /Users/kinsho/workspace/loginfrastructure/jitCompiler/target/scala-2.13/classes ...
...
[info] Compiling 5 Java sources to /Users/kinsho/workspace/loginfrastructure/jitCompiler/target/scala-2.13/classes ...
[success] Total time: 5 s, completed 2020/06/14 12:08:28
Eigentlich ausführen.
An [info] # VM-Version: JDK 1.8.0_232, OpenJDK 64-Bit-Server-VM, 25.232-b09
können Sie erkennen, dass sie mit der Standard-JVM ausgeführt wird.
sbt:jitCompiler> jmh:run
[info] running (fork) org.openjdk.jmh.Main
[info] # JMH version: 1.21
[info] # VM version: JDK 1.8.0_232, OpenJDK 64-Bit Server VM, 25.232-b09
[info] # VM invoker: /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/bin/java
[info] # VM options: <none>
[info] # Warmup: 1 iterations, single-shot each, 10000 calls per op
[info] # Measurement: 30 iterations, single-shot each, 10000 calls per op
[info] # Timeout: 10 min per iteration
[info] # Threads: 1 thread
[info] # Benchmark mode: Single shot invocation time
[info] # Benchmark: graal.GraalTest.run
[info] # Run progress: 0.00% complete, ETA 00:00:00
[info] # Fork: 1 of 1
[info] # Warmup Iteration 1: 1075.011 ms/op
[info] Iteration 1: 555.518 ms/op
[info] Iteration 2: 634.679 ms/op
[info] Iteration 3: 552.381 ms/op
[info] Iteration 4: 687.170 ms/op
[info] Iteration 5: 538.699 ms/op
[info] Iteration 6: 537.693 ms/op
[info] Iteration 7: 622.123 ms/op
[info] Iteration 8: 801.559 ms/op
[info] Iteration 9: 611.831 ms/op
[info] Iteration 10: 567.022 ms/op
[info] Iteration 11: 590.506 ms/op
[info] Iteration 12: 666.859 ms/op
[info] Iteration 13: 564.290 ms/op
[info] Iteration 14: 552.446 ms/op
[info] Iteration 15: 713.195 ms/op
[info] Iteration 16: 781.514 ms/op
[info] Iteration 17: 685.628 ms/op
[info] Iteration 18: 570.931 ms/op
[info] Iteration 19: 557.543 ms/op
[info] Iteration 20: 559.926 ms/op
[info] Iteration 21: 677.823 ms/op
[info] Iteration 22: 551.438 ms/op
[info] Iteration 23: 564.687 ms/op
[info] Iteration 24: 560.043 ms/op
[info] Iteration 25: 553.672 ms/op
[info] Iteration 26: 548.359 ms/op
[info] Iteration 27: 777.705 ms/op
[info] Iteration 28: 794.434 ms/op
[info] Iteration 29: 917.850 ms/op
[info] Iteration 30: 553.160 ms/op
[info] Result "graal.GraalTest.run":
[info] N = 30
[info] mean = 628.356 ±(99.9%) 67.159 ms/op
[info] Histogram, ms/op:
[info] [ 500.000, 550.000) = 3
[info] [ 550.000, 600.000) = 14
[info] [ 600.000, 650.000) = 3
[info] [ 650.000, 700.000) = 4
[info] [ 700.000, 750.000) = 1
[info] [ 750.000, 800.000) = 3
[info] [ 800.000, 850.000) = 1
[info] [ 850.000, 900.000) = 0
[info] [ 900.000, 950.000) = 1
[info] Percentiles, ms/op:
[info] p(0.0000) = 537.693 ms/op
[info] p(50.0000) = 568.977 ms/op
[info] p(90.0000) = 793.142 ms/op
[info] p(95.0000) = 853.890 ms/op
[info] p(99.0000) = 917.850 ms/op
[info] p(99.9000) = 917.850 ms/op
[info] p(99.9900) = 917.850 ms/op
[info] p(99.9990) = 917.850 ms/op
[info] p(99.9999) = 917.850 ms/op
[info] p(100.0000) = 917.850 ms/op
[info] # Run complete. Total time: 00:00:26
[info] REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
[info] why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
[info] experiments, perform baseline and negative tests that provide experimental control, make sure
[info] the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
[info] Do not assume the numbers tell you what you want them to tell.
[info] Benchmark Mode Cnt Score Error Units
[info] GraalTest.run ss 30 628.356 ± 67.159 ms/op
[success] Total time: 26 s, completed 2020/06/14 12:26:25
Die Ergebnisse werden schlampig beschrieben, aber zusammenfassend:
** Aufwärmzeit: 1075.011 ms / op ** ** Reine Geschwindigkeit: 628,356 ms / op **
ms / op
ist eine Einheit, die ausdrückt, wie lange es gedauert hat, die Zielmethode einmal auszuführen.
Da die Aufwärmzeit länger dauert als die reine Geschwindigkeit, können Sie auch sehen, dass sie nach 10.000 Aufwärmvorgängen normal kompiliert wird.
Diesmal der Favorit, gemessen mit GraalVM! Zuerst kompilieren.
sbt:jitCompiler> jmh:compile
[info] Compiling 3 Scala sources to /Users/kinsho/workspace/loginfrastructure/jitCompiler/target/scala-2.13/classes ...
...
[info] Compiling 5 Java sources to /Users/kinsho/workspace/loginfrastructure/jitCompiler/target/scala-2.13/classes ...
[success] Total time: 5 s, completed 2020/06/14 12:18:06
Lauf.
sbt:jitCompiler> jmh:run
Processing 9 classes from /Users/kinsho/workspace/loginfrastructure/jitCompiler/target/scala-2.13/classes with "reflection" generator
Writing out Java source to /Users/kinsho/workspace/loginfrastructure/jitCompiler/target/scala-2.13/src_managed/jmh and resources to /Users/kinsho/workspace/loginfrastructure/jitCompiler/target/scala-2.13/resource_managed/jmh
[info] running (fork) org.openjdk.jmh.Main
[info] # JMH version: 1.21
[info] # VM version: JDK 1.8.0_252, OpenJDK 64-Bit Server VM GraalVM CE 20.1.0, 25.252-b09-jvmci-20.1-b02
[info] # VM invoker: /Library/Java/JavaVirtualMachines/graalvm-ce-java8-20.1.0/Contents/Home/jre/bin/java
[info] # VM options: <none>
[info] # Warmup: 1 iterations, single-shot each, 10000 calls per op
[info] # Measurement: 30 iterations, single-shot each, 10000 calls per op
[info] # Timeout: 10 min per iteration
[info] # Threads: 1 thread
[info] # Benchmark mode: Single shot invocation time
[info] # Benchmark: graal.GraalTest.run
[info] # Run progress: 0.00% complete, ETA 00:00:00
[info] # Fork: 1 of 1
[info] # Warmup Iteration 1: 1012.169 ms/op
[info] Iteration 1: 546.073 ms/op
[info] Iteration 2: 584.707 ms/op
[info] Iteration 3: 547.958 ms/op
[info] Iteration 4: 662.077 ms/op
[info] Iteration 5: 549.202 ms/op
[info] Iteration 6: 490.277 ms/op
[info] Iteration 7: 620.376 ms/op
[info] Iteration 8: 780.583 ms/op
[info] Iteration 9: 576.626 ms/op
[info] Iteration 10: 508.686 ms/op
[info] Iteration 11: 543.451 ms/op
[info] Iteration 12: 589.145 ms/op
[info] Iteration 13: 515.498 ms/op
[info] Iteration 14: 524.002 ms/op
[info] Iteration 15: 717.083 ms/op
[info] Iteration 16: 839.723 ms/op
[info] Iteration 17: 523.987 ms/op
[info] Iteration 18: 519.271 ms/op
[info] Iteration 19: 525.304 ms/op
[info] Iteration 20: 530.935 ms/op
[info] Iteration 21: 634.322 ms/op
[info] Iteration 22: 545.711 ms/op
[info] Iteration 23: 513.338 ms/op
[info] Iteration 24: 518.737 ms/op
[info] Iteration 25: 519.130 ms/op
[info] Iteration 26: 575.139 ms/op
[info] Iteration 27: 745.525 ms/op
[info] Iteration 28: 774.832 ms/op
[info] Iteration 29: 830.160 ms/op
[info] Iteration 30: 549.396 ms/op
[info] Result "graal.GraalTest.run":
[info] N = 30
[info] mean = 596.708 ±(99.9%) 68.925 ms/op
[info] Histogram, ms/op:
[info] [400.000, 450.000) = 0
[info] [450.000, 500.000) = 1
[info] [500.000, 550.000) = 16
[info] [550.000, 600.000) = 4
[info] [600.000, 650.000) = 2
[info] [650.000, 700.000) = 1
[info] [700.000, 750.000) = 2
[info] [750.000, 800.000) = 2
[info] [800.000, 850.000) = 2
[info] Percentiles, ms/op:
[info] p(0.0000) = 490.277 ms/op
[info] p(50.0000) = 548.580 ms/op
[info] p(90.0000) = 780.008 ms/op
[info] p(95.0000) = 834.463 ms/op
[info] p(99.0000) = 839.723 ms/op
[info] p(99.9000) = 839.723 ms/op
[info] p(99.9900) = 839.723 ms/op
[info] p(99.9990) = 839.723 ms/op
[info] p(99.9999) = 839.723 ms/op
[info] p(100.0000) = 839.723 ms/op
[info] # Run complete. Total time: 00:00:25
[info] REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
[info] why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
[info] experiments, perform baseline and negative tests that provide experimental control, make sure
[info] the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
[info] Do not assume the numbers tell you what you want them to tell.
[info] Benchmark Mode Cnt Score Error Units
[info] GraalTest.run ss 30 596.708 ± 68.925 ms/op
[success] Total time: 26 s, completed 2020/06/14 12:22:50
Die Ergebnisse werden auch diesmal schlampig beschrieben, aber zusammenfassend:
** Aufwärmzeit: 1012,169 ms / op ** ** Reine Ausführungszeit: 596.708 ms / op **
Als Ergebnis der Messung wurde festgestellt, dass Graal schneller war. (Wenn diese Messmethode korrekt ist, scheint es mehr Punkte zu geben, die berücksichtigt werden müssen.)