一些杂想:Java老矣,尚能饭否?( 七 )


从我目前搜到的一些测试结果来看 , 总的来说Graal编译结果的性能与C2相比略优但相差不大 。Graal在基于假设的优化手段上相对更激进 , 因此在某些场景下优势会更明显(比如这篇文章[61] , 再比如的报告[62]讲的Scala代码性能上Graal有10%的优势) 。最关键的是 , Graal还在不断演进中 , 未来可期 。
VM
VM简单来说就是 image +  , 分别对应原生镜像( Image)[63]的build time和run time 。
官网放了一张图来展示GraalImage的两大优势:快速启动和低内存占用 。不过我看到的其他一些资料上说在低时延和高吞吐(/)场景下并不占优 。
VM的限制其实就是前面说的AOT编译的限制 , 要求目标程序满足"-world"假设 , 即所有代码在编译器已知 。如果不满足 , 那只能同时构建一个 image了(使用传统JVM执行 , 需要JDK依赖) 。一些限制条件可以通过在镜像构建时进行配置[64]来绕过 , 其中最关键的就是类的元数据()相关的一些限制:
还有一些限制条件 , 像是字节码和  , 是直接无法兼容的 。还有一些功能跟有区别 , 具体可以参考这篇文档[66] 。
是一个用Java写的语言实现框架 , 也可以说是一套通用语言设计的框架和API 。除了像 Java、Scala、、 等基于JVM的语言外 , 官方在此之上还支持了[67]、Ruby[68]、R[69]、[70]、[71](LLVM-based C/C++等) , 也就是说这些语言都可以“跑在”上 , 号称"Run" 。
完整的列表参考这里[72] 。
这是我找到的一份17年的性能数据 , 可以看到除了C/C++和JS之外 , 的性能优势还是挺大的 , 尤其是对于Ruby、R这类解释型语言 。
提供了一套API , 基于的语言实现仅需用Java实现词法分析、语法分析以及针对语法分析所生成的抽象语法树(AST)的解释器 , 理论上实现一个解释器要比开发一个优化的编译器要容易得多 。将这些语言的源代码或源代码编译后的中间格式(例如 , LLVM 字节码、Class 字节码)通过解释器转换为能被接受的中间表示(  , IR) , 然后就可以使用Graal编译器对这些解释器进行优化 , 因此性能上有时候比传统编译器反而还有优势 。
此外 , 的精华之处在于 , 运行时所有的解释器都通过同样的协议来互相操作不同编程语言中的对象 , 这就为所有生态系统下的库和模块都敞开了大门 , 你只需要选择最合适的语言去解决你要解决的问题就可以了 , 而不用为了项目所用的某个语言去专门实现一些缺少的模块 。
这是一个官方的示例 , 展示了多语言如何直接进行交互:
const express = require('express')const app = express()const BigInteger = Java.type('java.math.BigInteger')app.get('/', function (req, res) {var text = 'Hello World from Graal.js!
'
// Using Java standard library classestext += BigInteger.valueOf(10).pow(100).add(BigInteger.valueOf(43)).toString() + '
'
// Using R methods to return arraystext += Polyglot.eval('R','ifelse(1 > 2, "no", paste(1:42, c="|"))') + '
'
// Using R interoperability to create graphstext += Polyglot.eval('R',`svg();require(lattice);x <- 1:100y <- sin(x/10)z <- cos(x^1.3/(runif(1)*5+10))print(cloud(x~y*z, main="cloud plot"))