GraalVM是JVM块的新成员。 它是一个开源虚拟机,能够同时运行多种编程语言,例如Java,Rust和JavaScript。 GraalVM还有一个新的内部代码优化器管道,在某些情况下,与其他JVM相比,它可以显着提高性能。 了解如何获得GraalVM的好处并无需修改代码即可更快地执行代码。
什么是GraalVM?
以前的JVM,例如Oracle JVM和OpenJDK JVM(均称为“ HotSpot”),已经存在了很长时间。 随着时间的推移,它们已经有了长足的发展,并且在过去的几十年中,与Java 1.0 JVM相比,我们看到了性能飞速增长。 JVM的重大改进包括即时编译(JIT),C2编译器,转义分析等,这些都为这一积极的发展做出了贡献。 但是,与所有技术一样,它们将在某个时候开始达到平稳状态。
GraalVM是一个崭新的开始,由此从头开始开发新的内部架构。 特别是,名为Gaal的JIT编译器已经过重新设计。 毫不奇怪,就像所有其他GraalVM组件一样,JIT编译器本身是用Java编写的。 事实证明,与某些现有的JVM相比,Graal有时能够更好地优化代码。 特别是,某些Stream类型似乎受益于在Graal下运行。
数据库流性能
有许多编写Java流的方法。 最明显的方法是使用内置的Java函数Stream::of
或Collection::stream
方法之一。 但是,这些方法要求Stream中的元素以Java对象的形式先验存在。 这意味着编译器无法在大多数情况下优化它们。
因此,我选择使用基于流的ORM工具Speedment。 该工具与一项技术结合使用,该技术可将数据库内容提取到JVM内存中的快照中,并直接从RAM中创建Java流。 因此,数据库表是堆外存储的,从而有可能避免创建Java对象。 因为Graal具有改进的性能优化管道,所以它可能可以更好地优化临时中间流对象。 从理论上讲,Speedment和Graal将是一个完美的选择。 因此,我非常渴望测试
在GraalVM而不是HotSpot下运行时,Speedement的极端性能将受到影响。
以下Speedment数据库流用于测试性能。 在我的上一篇文章中可以找到有关这些流及其工作方式的更多信息,您可以在这里找到。
private static final Predicate RATING_EQUALS_PG_13 =Film.RATING.equal(GeneratedFilm.Rating.PG13);private static final Comparator LENGTH_DESCENDING = Film.LENGTH.reversed();@Benchmark
public long filterAndCount() {return films.stream().filter(RATING_EQUALS_PG_13).count();
}@Benchmark
public IntSummaryStatistics Complex() {return films.stream().sorted(LENGTH_DESCENDING).skip(745).limit(5).mapToInt(Film.RENTAL_DURATION.asInt()).summaryStatistics();
}
分别在GraalVM和HotSpot下运行时获得以下JMH输出:
Graal:
Benchmark Mode Cnt Score Error Units
Bench.Complex thrpt 5 8453285.715 ± 383634.200 ops/s
Bench.filterAndCount thrpt 5 29755350.558 ± 674240.743 ops/sHotSpot:
Benchmark Mode Cnt Score Error Units
Bench.Complex thrpt 5 5334041.755 ± 176368.317 ops/s
Bench.filterAndCount thrpt 5 20809826.960 ± 963757.357 ops/s
拥有4个CPU内核的笔记本电脑上的GraalVM / Speedment能够每秒产生和消耗超过3000万个数据库流,这真是令人惊讶。 想象一下在具有24或32个CPU内核的服务器级节点上的性能。
这是它在图表中的外观(越高越好):
普通流性能
初始测试显示了针对不同JVM的内置Java流(如Stream.of(“A”, “B”, “C”)
或List::stream
Stream.of(“A”, “B”, “C”)
不同相对性能指标,这些List::stream
了各种操作。 我希望一旦GraalVM成熟,这些流类型也将全面提高性能。 也许我会在以后的文章中介绍。
设定
以下JMH设置用于GraalVM和HotSpot:
# Detecting actual CPU count: 8 detected
# JMH version: 1.21
# VM version: JDK 1.8.0_172, GraalVM 1.0.0-rc6, 25.71-b01-internal-jvmci-0.48
# *** WARNING: JMH support for this VM is experimental. Be extra careful with the produced data.
# VM invoker: /Applications/graalvm-ce-1.0.0-rc6/Contents/Home/jre/bin/java
# VM options: -Dfile.encoding=UTF-8
# Warmup: 5 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 8 threads, will synchronize iterations
# Benchmark mode: Throughput, ops/time# Detecting actual CPU count: 8 detected
# JMH version: 1.21
# VM version: JDK 1.8.0_171, Java HotSpot(TM) 64-Bit Server VM, 25.171-b11
# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/bin/java
# VM options: -Dfile.encoding=UTF-8
# Warmup: 5 iterations, 10 s each
# Measurement: 5 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 8 threads, will synchronize iterations
# Benchmark mode: Throughput, ops/time
上面的测试是在MacBook Pro(Retina,15英寸,2015年中),2.2 GHz Intel Core i7、16 GB 1600 MHz DDR3(具有4个CPU内核和8个线程)上进行的。 从日志中可以看出,我们应该谨慎地使用JMH的Graal得出结论,因为JMH支持目前处于试验阶段。
旋转一下
使用Speedment初始化创建Speedment项目模板这里 。
在此处下载最新版本的GraalVM。
可以在此处找到基准测试的源代码。
随时在另一个硬件平台上进行性能测试,并在下面的评论中报告结果。
结论
GraalVM接缝是一种有前途的技术,可以提高某些Java流类型的性能。
GraalVM与Speedment的JVM内存中加速结合使用可以为数据分析应用程序提供显着的流性能。
翻译自: https://www.javacodegeeks.com/2018/10/java-graalvm-database-stream-performance.html