GraalVM可以做的十件事


译者的话:GraalVM是一项有趣的新技术,但是在Habré上,没有多少文章可以展示Graal功能的示例。 下面的文章不仅列出了GraalVM的功能,而且还类似于Chris Seaton和Oleg Shelaev在Oracle CodeOne 2018上进行的小型大师班。在作者之后,我敦促您尝试从本文中举例说明,有趣。


GraalVM中有很多不同的事情,如果您以前听过这个名字,甚至看到过报告,您可能仍然不知道很多事情,但是GraalVM可以做什么。 在本文中,我们将介绍GraalVM提供的各种功能,并展示您可以使用它们做什么。


  1. Java快速执行
  2. 减少Java的启动时间和内存使用量
  3. 结合JavaScript,Java,Ruby和R
  4. 执行以平台特定语言编写的程序
  5. 所有编程语言的通用工具
  6. JVM应用程序补充
  7. 平台相关的应用
  8. Java代码作为特定于平台的库
  9. 支持数据库中的多种编程语言
  10. 为GraalVM创建编程语言

您可以使用GraalVM 1.0.0 RC1完成本文中显示的所有操作,可通过GraalVM网站上的链接获得该功能 。 我使用了MacOS Enterprise Edition,但此处编写的代码将在Linux和GraalVM Community Edition上运行。


阅读本文时,请运行其中描述的程序! 可以从GitHub下载代码。


安装方式


http://graalvm.org/downloads下载后我在$PATH添加了GraalVM可执行文件的$PATH 。 默认情况下,这增加了对Java和JavaScript执行的支持。


 $ git clone https://github.com/chrisseaton/graalvm-ten-things.git $ cd foo $ tar -zxf graalvm-ee-1.0.0-rc1-macos-amd64.tar.gz # or graalvm-ee-1.0.0-rc1-linux-amd64.tar.gz on Linux $ export PATH=graalvm-1.0.0-rc1/Contents/Home/bin:$PATH # or PATH=graalvm-1.0.0-rc1/bin:$PATH on Linux 

GraalVM带有内置的JavaScript支持,并包含一个名为gu的软件包管理器,该软件包管理器增加了安装对Java和JavaScript以外的语言的支持的功能。 我还安装了Ruby,Python和R,它们是从GitHub下载的。


 $ gu install -c org.graalvm.ruby $ gu install -c org.graalvm.python $ gu install -c org.graalvm.R 

现在,如果执行javajs命令,您将看到这些引擎的GraalVM版本。


 $ java -version java version "1.8.0_161" Java(TM) SE Runtime Environment (build 1.8.0_161-b12) GraalVM 1.0.0-rc1 (build 25.71-b01-internal-jvmci-0.42, mixed mode) $ js --version Graal JavaScript 1.0 (GraalVM 1.0.0-rc1) 

1.快速执行Java


GraalVM中的“ Graal”是编译器的名称。 他一个人被创造来统治一切 ! 这意味着这是一个以库的形式编写的编译器实现,可以用于许多不同的事情。 例如,我们使用Graal 提前编译和及时编译,以编译用不同编程语言(包括用于不同处理器体系结构)编写的代码。


使用Graal的第一种也是最简单的方法是将其用作Java JIT编译器。


例如,我们将使用一个程序,该程序在文档中产生10个最常见的单词。 该程序使用了现代Java语言的功能,例如流和集合。


 import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; public class TopTen { public static void main(String[] args) { Arrays.stream(args) .flatMap(TopTen::fileLines) .flatMap(line -> Arrays.stream(line.split("\\b"))) .map(word -> word.replaceAll("[^a-zA-Z]", "")) .filter(word -> word.length() > 0) .map(word -> word.toLowerCase()) .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())) .entrySet().stream() .sorted((a, b) -> -a.getValue().compareTo(b.getValue())) .limit(10) .forEach(e -> System.out.format("%s = %d%n", e.getKey(), e.getValue())); } private static Stream<String> fileLines(String path) { try { return Files.lines(Paths.get(path)); } catch (IOException e) { throw new RuntimeException(e); } } } 

GraalVM包含javac编译器,但是此演示无论使用它还是使用标准编译器都没有区别。 因此,您可以根据需要使用标准的javac编译器。


 $ javac TopTen.java 

如果我们运行GraalVM中包含的java命令,那么Grait JIT编译器将自动使用-无需其他步骤。 我将使用time命令来获取有关从头到尾执行程序所花费时间的真实数据,而不是部署复杂的微基准测试。 也将使用大量输入,因此不会在这里或那里暗示所节省的几秒钟。 large.txt文件的大小为150 MB。


 $ make large.txt $ time java TopTen large.txt sed = 502701 ut = 392657 in = 377651 et = 352641 id = 317627 eu = 317627 eget = 302621 vel = 300120 a = 287615 sit = 282613 real 0m17.367s user 0m32.355s sys 0m1.456s 

像大多数其他Java的JIT编译器一样,Graal用Java而不是C ++编写。 我们认为,这使我们能够比现有的编译器更快地对其进行改进,并添加了针对HotSpot的标准JIT编译器中不提供的新的强大优化(例如,部分转义分析)。
这可以使您的Java程序更快。


为了进行比较,要在没有Grait JIT编译器的情况下运行程序,我将使用-XX:-UseJVMCICompiler 。 JVMCI是Graal和JVM之间的接口。 您还可以在标准JVM上运行该示例并比较结果。


 $ time java -XX:-UseJVMCICompiler TopTen large.txt sed = 502701 ut = 392657 in = 377651 et = 352641 id = 317627 eu = 317627 eget = 302621 vel = 300120 a = 287615 sit = 282613 real 0m23.511s user 0m24.293s sys 0m0.579s 

该测试表明,Graal使用标准的HotSpot编译器运行Java程序的时间大约为四分之三。 我们认为以百分比为单位提高生产力是一项重大成就,而25%的意义重大。


Twitter是当今唯一一家在“战斗”服务器上使用Graal的公司,并且他们说,这样做对节省资金是有道理的。 Twitter使用Graal执行用Scala编写的应用程序-Graal在JVM字节码级别上工作,即 适用于任何JVM语言。


这是GraalVM的第一个用例-只需用现有Java应用程序的更好版本替换JIT编译器。


2.减少Java的启动时间和内存使用量


当使用长时间运行的进程和峰值负载时,Java平台的优势尤其明显。 相比之下,寿命短的进程则需要较长的启动时间和相对较高的内存使用量。


例如,如果我们运行上一节中的应用程序,向它提供少量的输入数据-大约1Kb而不是150MB,那么为了处理这么小的文件,似乎将花费不合理的时间和大量的内存-大约60MB。 。 除了执行时间以外,我们还使用-l选项来打印已使用的内存量。


 $ make small.txt $ /usr/bin/time -l java TopTen small.txt # -v on Linux instead of -l sed = 6 sit = 6 amet = 6 mauris = 3 volutpat = 3 vitae = 3 dolor = 3 libero = 3 tempor = 2 suscipit = 2 0.32 real 0.49 user 0.05 sys 59846656 maximum resident set size 

GraalVM为我们提供了解决此问题的工具。 我们说过Graal是一个编译器库,可以用许多不同的方式使用。 其中之一是提前编译为依赖于平台的可执行映像,而不是在运行时即时编译。 这类似于常规编译器(例如gcc


 $ native-image --no-server TopTen classlist: 1,513.82 ms (cap): 2,333.95 ms setup: 3,584.09 ms (typeflow): 4,642.13 ms (objects): 3,073.58 ms (features): 156.34 ms analysis: 8,059.94 ms universe: 353.02 ms (parse): 1,277.02 ms (inline): 1,412.08 ms (compile): 10,337.76 ms compile: 13,776.23 ms image: 2,526.63 ms write: 1,525.03 ms [total]: 31,439.47 ms 

此命令创建一个平台topten称为topten 。 该文件不会启动JVM,它没有链接到JVM,并且它不以任何方式包括JVM。 native-image命令可将您的Java代码和您使用的Java库真正编译为完整的机器代码。 对于运行时组件(例如垃圾收集器),我们启动了自己的新虚拟机,称为SubstrateVM,与Graal一样,它也是用Java编写的。


如果查看topten使用的依赖项,您将看到它们只是标准系统库。 我们只能将这一个文件传输到从未安装过JVM的系统中,然后在该系统中运行该文件以确认它不使用JVM或任何其他文件。 Topten也非常小-可执行代码占用的Topten不到6 MB。


 $ otool -L topten # ldd topten on Linux topten: .../CoreFoundation.framework ... .../libz.1.dylib ... .../libSystem.B.dylib ... $ du -h topten 5.7M topten 

如果运行此可执行文件,我们将看到它的启动速度比在JVM下运行的同一程序快大约一个数量级,并且使用的内存少大约一个数量级。 发射是如此之快,您几乎不会注意到它花了多长时间。 如果使用命令行,当您在JVM下运行一个短暂的小型程序时,通常不会出现暂停现象


 $ /usr/bin/time -l ./topten small.txt sed = 6 sit = 6 amet = 6 mauris = 3 volutpat = 3 vitae = 3 dolor = 3 libero = 3 tempor = 2 suscipit = 2 0.02 real 0.00 user 0.00 sys 4702208 maximum resident set size 

native-image实用程序有一些限制 。 因此,在编译时,应该提供所有类,并且在使用Reflection API方面也有一些限制。 但是,与基本编译相比,还有其他一些优点,例如在编译时执行静态初始化程序。 因此,减少了每次下载应用程序时执行的工作量。


这是GraalVM的第二个应用程序-现有Java程序的分发和执行,具有快速启动和较少的内存消耗的功能。 此方法修复了配置问题,例如在运行时找到正确的jar,还允许您创建较小的docker映像。


3.结合JavaScript,Java,Ruby和R


与Java一起,GraalVM包括JavaScript,Ruby,R和Python引擎的新实现。 它们是使用称为Truffle的新框架编写的。 该框架使创建简单而高性能的语言解释器成为可能。 当您使用Truffle编写语言解释器时,它将自动使用Graal为您的语言提供JIT编译。 因此,Graal不仅是Java的JIT编译器和AOT编译器,而且还可以是JavaScript,Ruby,R和Python的JIT编译器。


GraalVM中对第三方语言的支持旨在透明替代现有引擎,以执行各种语言。 例如,我们可以为Node.js安装“颜色”模块:


 $ npm install --global color ... + color@3.0.0 added 6 packages in 14.156s 

然后使用该模块编写一个程序,将RGB HTML颜色转换为HSL:


 var Color = require('color'); process.argv.slice(2).forEach(function (val) { print(Color(val).hsl().string()); }); 

并以通常的方式运行它:


 $ node color.js '#42aaf4' hsl(204.89999999999998, 89%, 60.8%) 

GraalVM中不同语言的执行引擎可以协同工作-有一个API,使您可以在用另一种语言编写的程序中从一种语言运行代码。 这样,您就可以编写多语言程序-用一种以上的编程语言编写的程序。


如果您使用一种语言编写大多数程序,但是想使用以另一种编程语言编写的库,则可能有必要。 例如,假设我们需要编写一个应用程序来将颜色名称从CSS转换为Node.js中的数字表示形式,但是我们想使用Ruby颜色库而不是自己编写转换。


 var express = require('express'); var app = express(); color_rgb = Polyglot.eval('ruby', ` require 'color' Color::RGB `); app.get('/css/:name', function (req, res) { color = color_rgb.by_name(req.params.name).html() res.send('<h1 style="color: ' + color + '" >' + color + '</h1>'); }); app.listen(8080, function () { console.log('serving at http://localhost:8080') }); 

在这段代码中,我们写道我们需要将Ruby代码作为字符串执行,但是请注意,我们在这里并没有做太多事情-我们只是连接了库,然后返回了Ruby对象。 在Ruby中,我们将这样使用它: Color::RGB.by_name (name).html 。 如果您稍后查看如何在JavaScript中使用color_rgb ,您将看到我们实际上从JavaScript调用了相同的方法,尽管它们是Ruby对象和方法。 然后将它们作为JavaScript字符串传递,并将结果(一个Ruby字符串)与一个JavaScript字符串组合在一起。


安装两个依赖项-Ruby和JavaScript。


 $ gem install color Fetching: color-1.8.gem (100%) Successfully installed color-1.8 1 gem installed $ npm install express + express@4.16.2 updated 1 package in 10.393s 

然后,您需要使用两个附加选项来启动node :-- --polyglot ,也就是说我们需要访问其他语言和--jvm ,因为默认情况下, node的可执行映像不包含JavaScript以外的任何内容。


 $ node --polyglot --jvm color-server.js serving at http://localhost:8080 

然后,像往常一样,在浏览器中转到URL http://本地主机:8080 / css / orange (或其他颜色)。

让我们尝试做一个更严肃的例子,它使用更多的语言和模块。


JavaScript不支持非常大的整数。 我发现了几个模块,例如big-integer ,但是它们都效率不高,因为 将数字的组成部分存储为JavaScript浮点数。 Java中的BigInteger类效率更高,让我们使用它对大整数进行一些算术运算。


JavaScript也没有内置的图形绘制支持,而R可以出色地绘制图形。 让我们使用R中的svg模块在3D空间中绘制三角函数的散点图。


在这两种情况下,我们都将使用该API支持GraalVM的多种语言(以下称为Polyglot API),并且我们可以简单地将其他语言的程序执行结果插入JavaScript。


 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!<br> ' // Using Java standard library classes text += BigInteger.valueOf(10).pow(100) .add(BigInteger.valueOf(43)).toString() + '<br>' // Using R interoperability to create graphs text += Polyglot.eval('R', `svg(); require(lattice); x <- 1:100 y <- sin(x/10) z <- cos(x^1.3/(runif(1)*5+10)) print(cloud(x~y*z, main="cloud plot")) grDevices:::svg.off() `); res.send(text) }) app.listen(3000, function () { console.log('Example app listening on port 3000!') }) 

在浏览器中打开http:// localhost:3000 /以查看结果:

这是我们使用GraalVM可以做的第三件事-运行以多种语言编写的程序,并在一个程序中一起使用这些语言的模块。 我们将其作为统一运行时环境和库的一种方式-您可以使用认为最适合解决当前任务的编程语言以及所需的任何库,而无需考虑使用哪种编程语言。


4.以平台特定语言编写的程序的执行


GraalVM支持的另一种语言是C。GraalVM可以执行C代码,就像执行以JavaScript和Ruby编写的程序一样。


GraalVM实际支持的是执行LLVM实用程序所产生的代码,即 位代码,而不是直接支持C。这意味着您可以使用现有的C语言工具以及其他支持LLVM的工具,例如C ++,Fortran以及将来可能使用的更多语言。 为了简化演示,我运行了一个特殊版本的gzip ,该版本在一个文件中组装( Stephen McCamant支持该版本)。 为了简单起见,这只是gzip源代码和autoconf配置组合到一个文件中。 我必须修补一些东西才能使其在macOS和clang上运行,但是我没有做任何专门支持GraalVM的事情。


我们使用标准的clang (用于C的LLVM编译器)编译gzip,并希望它使我们成为LLVM位代码,而不是特定于平台的版本,因为GraalVM不会启动它。 我正在使用clang 4.0.1。


 $ clang -c -emit-llvm gzip.c 

然后直接使用GraalVM的lli命令(LLVM位代码解释器)运行结果。 让我们尝试使用我的gzip系统存档程序压缩文件,然后使用在GraalVM下运行的gzip解压缩文件。


 $ cat small.txt Lorem ipsum dolor sit amet... $ gzip small.txt $ lli gzip.bc -d small.txt.gz $ cat small.txt Lorem ipsum dolor sit amet... 

GraalVM中的Ruby和Python实现使用相同的技术来运行用C语言编写的针对这些语言的扩展。 这意味着您可以在VM内运行这些扩展,即使我们使用了特定于平台的扩展接口,也可以使我们保持较高的执行速度。


这是使用GraalVM的第四种方法-运行以特定于平台的语言(例如C或C ++)编写的程序,以及启动对诸如Python或Ruby之类的语言的扩展,这些扩展无法使这些语言的JVM实现成为可能,例如JRuby。


5.适用于所有编程语言的通用工具


如果您使用Java编程,则可能使用的是非常高质量的工具,例如IDE,调试器和分析器。 并非所有语言都具有此工具包,但是如果您使用GraalVM支持的语言,则可以获得一个工具包。


使用通用框架-Truffle实现了对GraalVM中所有语言(目前不包括Java)的支持。 这样,我们便可以一次创建该功能(例如调试器),并将其用于所有语言。


为此,我们将编写最简单的程序FizzBu​​zz ,因为它是可视的(在屏幕上打印出一些东西),并且具有清晰的分支,仅在某些迭代中使用。 因此,对我们来说设置断点将更加容易。 让我们从JavaScript实现开始。


 function fizzbuzz(n) { if ((n % 3 == 0) && (n % 5 == 0)) { return 'FizzBuzz'; } else if (n % 3 == 0) { return 'Fizz'; } else if (n % 5 == 0) { return 'Buzz'; } else { return n; } } for (var n = 1; n <= 20; n++) { print(fizzbuzz(n)); } 

我们使用GraalVM下的js实用程序照常启动程序。


 $ js fizzbuzz.js 1 2 Fizz 4 Buzz Fizz 

我们还可以使用--inspect标志运行该程序。 这将为我们提供一个链接,您可以在Chrome中打开该链接并在调试器中停止该程序。


 $ js --inspect fizzbuzz.js Debugger listening on port 9229. To start debugging, open the following URL in Chrome: chrome-devtools://devtools/bundled/inspector.html?ws=127.0.0.1:9229/6c478d4e-1350b196b409 

您可以在FizzBu​​zz代码中设置一个断点,然后继续执行。 当程序中断执行时,我们将在调试器中看到变量n的值,我们可以继续执行程序或研究调试器接口。

Chrome中的调试器通常用于JavaScript,但JavaScript中的GraalVM与其他语言没有什么不同。 --inspect标志也可用,并且可以在Python,Ruby和R实现中使用。我不会向您展示每个程序的源代码,但是它们以相同的方式运行,并且您在Chrome中为每个程序都使用了相同的调试器。


 $ graalpython --jvm --inspect fizzbuzz.py 


 $ ruby --inspect fizzbuzz.rb 


 $ Rscript --inspect fizzbuzz.r 


您可能从Java熟悉的另一个工具是VisualVM。 它提供了一个用户界面,通过该用户界面,您可以在本地计算机上或通过网络加入正在运行的JVM,以检查程序执行的各个方面,例如内存使用或线程执行。


GraalVM包括VisualVM作为标准的jvisualvm实用程序。


 $ jvisualvm &> /dev/null & 

如果在TopTen Java程序运行时运行VisualVM,则可以观察内存使用情况,例如,对内存内容进行快照,并查看我们在堆上使用内存的对象类型。


 $ java TopTen large.txt 


我用Ruby编写了此程序,以便在运行时在内存中生成一些垃圾。


 require 'erb' x = 42 template = ERB.new <<-EOF The value of x is: <%= x %> EOF loop do puts template.result(binding) end 

如果您在JVM-JRuby上运行标准Ruby实现,您将对VisualVM感到失望,因为您只会看到内部Java对象,而不是您所用语言的对象。


如果使用Ruby for GraalVM版本,则VisualVM可以识别Ruby对象。 我们需要使用--jvm选项来使用VisualVM,因为 它不支持Ruby的本机版本。


 $ ruby --jvm render.rb 

, , Java , , , Summary, Ruby Heap Ruby .

Truffle — - Nexus . Truffle , , API Truffle' , , Truffle, .


, GraalVM — , . Truffle GraalVM , VisualVM.


6. JVM


, , , Java . API org.graalvm.polyglot , .


 import org.graalvm.polyglot.Context; import org.graalvm.polyglot.Value; public class ExtendJava { public static void main(String[] args) { String language = "js"; try (Context context = Context.newBuilder().allowNativeAccess(true).build()) { for (String arg: args) { if (arg.startsWith("-")) { language = arg.substring(1); } else { Value v = context.eval(language, arg); System.out.println(v); } } } } } 

javac java GraalVM, org.graalvm.* classpath , .. .


 $ javac ExtendJava.java $ java ExtendJava '14 + 2' 16 $ java ExtendJava -js 'Math.sqrt(14)' 3.7416573867739413 $ java ExtendJava -python '[2**n for n in range(0, 8)]' [1, 2, 4, 8, 16, 32, 64, 128] $ java ExtendJava -ruby '[4, 2, 3].sort' [2, 3, 4] 

, — , node ruby , GraalVM.


GraalVM — Java . Polyglot API “” Java , .


7. -


GraalVM , , — , , GraalVM, - . , JavaScript , V8, Python — CPython , .. . GraalVM — Polyglot .


GraalVM, , JavaScript. Polyglot , , :


 $ graalvm-1.0.0-rc1/Contents/Home/jre/lib/svm/bin/rebuild-images libpolyglot 

C, , , GraalVM, . ExtendJava , , .


 #include <stdlib.h> #include <stdio.h> #include <polyglot_api.h> int main(int argc, char **argv) { graal_isolate_t *isolate = NULL; graal_isolatethread_t *thread = NULL; if (graal_create_isolate(NULL, &isolate) != 0 || (thread = graal_current_thread(isolate)) == NULL) { fprintf(stderr, "initialization error\n"); return 1; } poly_context context = NULL; if (poly_create_context(thread, NULL, 0, &context) != poly_ok) { fprintf(stderr, "initialization error\n"); return 1; } char* language = "js"; for (int n = 1; n < argc; n++) { if (argv[n][0] == '-') { language = &argv[n][1]; } else { poly_value result = NULL; if (poly_context_eval(thread, context, language, "unicalc", argv[n], &result) != poly_ok) { fprintf(stderr, "eval error\n"); return 1; } char buffer[1024]; size_t length; if (poly_value_to_string_utf8(thread, result, buffer, sizeof(buffer), &length) != poly_ok) { fprintf(stderr, "to string error\n"); return 1; } buffer[length] = '\0'; printf("%s\n", buffer); poly_destroy_handle(thread, result); } } return 0; } 

, polyglot GraalVM. , , JVM.


 $ clang -Igraalvm-1.0.0-rc1/Contents/Home/jre/lib/polyglot / -rpath graalvm-1.0.0-rc1/Contents/Home / -Lgraalvm-1.0.0-rc1/Contents/Home/jre/lib/polyglot / -lpolyglot extendc.c -o extendc $ otool -L extendc extendc: .../libpolyglot.dylib ... .../libSystem.B.dylib ... 

 $ ./extendc '14 + 2' 16 $ ./extendc -js 'Math.sqrt(14)' 3.7416573867739413 $ ./extendc -python '[2**n for n in range(0, 8)]' [1, 2, 4, 8, 16, 32, 64, 128] 

, GraalVM — - , , GraalVM.


8. Java -


Java , , , , - , . Java - , JVM , .


GraalVM Java , , - , . , , Java JVM.


, Apache SIS , ( ) . SIS 0.8, http://sis.apache.org/ jar.


 import org.apache.sis.distance.DistanceUtils; public class Distance { public static void main(String[] args) { final double aLat = Double.parseDouble(args[0]); final double aLong = Double.parseDouble(args[1]); final double bLat = Double.parseDouble(args[2]); final double bLong = Double.parseDouble(args[3]); System.out.printf("%.2f km%n", DistanceUtils.getHaversineDistance(aLat, aLong, bLat, bLong)); } public static double distance(IsolateThread thread, double aLat, double aLong, double bLat, double bLong) { return DistanceUtils.getHaversineDistance(aLat, aLong, bLat, bLong); } } 

, -


 $ javac -cp sis.jar -parameters Distance.java $ java -cp sis.jar:. Distance 51.507222 -0.1275 40.7127 -74.0059 5570.25 km 

, topten .


 $ native-image --no-server -cp sis.jar:. Distance ... $ ./distance 51.507222 -0.1275 40.7127 -74.0059 5570.25 km 

, . , @CEntryPoint


 ... import org.graalvm.nativeimage.IsolateThread; import org.graalvm.nativeimage.c.function.CEntryPoint; public class Distance { ... @CEntryPoint(name = "distance") public static double distance(IsolateThread thread, double a_lat, double a_long, double b_lat, double b_long) { return DistanceUtils.getHaversineDistance(a_lat, a_long, b_lat, b_long); } ... } 

javac , GraalVM API classpath . C .


 $ native-image --no-server -cp sis.jar:. -H:Kind=SHARED_LIBRARY \ -H:Name=libdistance $ otool -L libdistance.dylib # .so on Linux libdistance.dylib: .../libdistance.dylib ... .../CoreFoundation.framework ... .../libz.1.dylib ... .../libSystem.B.dylib ... $ du -h libdistance.dylib 4.8M libdistance.dylib 

, . , : VM , , .


 #include <stdlib.h> #include <stdio.h> #include <libdistance.h> int main(int argc, char **argv) { graal_isolate_t *isolate = NULL; graal_isolatethread_t *thread = NULL; if (graal_create_isolate(NULL, &isolate) != 0 || (thread = graal_current_thread(isolate)) == NULL) { fprintf(stderr, "initialization error\n"); return 1; } double a_lat = strtod(argv[1], NULL); double a_long = strtod(argv[2], NULL); double b_lat = strtod(argv[3], NULL); double b_long = strtod(argv[4], NULL); printf("%.2f km\n", distance(thread, a_lat, a_long, b_lat, b_long)); return 0; } 

, ( LD_LIBRARY_PARTH=. Linux)


 $ clang -I. -L. -ldistance distance.c -o distance $ otool -L distance distance: .../libdistance.dylib ... .../libSystem.B.dylib ... $ ./distance 51.507222 -0.1275 40.7127 -74.0059 5570.25 km 

GraalVM — java - , JVM


9.


Polyglot — Oracle. Oracle Database Multilingual Engine (MLE), GraalVM SQL.


, front-end, JavaScript email , JavaScript validator . - , SQL PL/SQL. , .


MLE Docker :


https://oracle.imtqy.com/oracle-db-mle/releases/0.2.7/docker/


Docker Daemon.


 $ docker load --input mle-docker-0.2.7.tar.gz 

, Docker, , ( ), Bash .


 $ docker run mle-docker-0.2.7 $ docker ps $ docker exec -ti <container_id> bash -li 

sqlplus ( SQL ), Bash, , , .


 $ sqlplus scott/tiger@localhost:1521/ORCLCDB 

, sqlplus . , Bash Docker, dbjs , . sqlplus .


 $ npm install validator $ npm install @types/validator $ dbjs deploy -u scott -p tiger -c localhost:1521/ORCLCDB validator $ sqlplus scott/tiger@localhost:1521/ORCLCDB 

validator SQL .


 SQL> select validator.isEmail('hello.world@oracle.com') from dual; VALIDATOR.ISEMAIL('HELLO.WORLD@ORACLE.COM') ------------------------------------------- 1 SQL> select validator.isEmail('hello.world') from dual; VALIDATOR.ISEMAIL('HELLO.WORLD') -------------------------------- 0 

, GraalVM — , GraalVM, Oracle. , front-end back-end, , , .


10. GraalVM


Oracle Labs JavaScript, R, Ruby, Python C , Truffle, GraalVM.


Truffle — java , (AST). AST — , , , , , . , , Truffle Graal JIT , AST .


Truffle, GraalVM , , DSL. Truffle Graal , , Truffle — GraalVM. , , , , . , , . Oracle labs Ruby , , .


, , , SimpleLanguage — Truffle, JavaScript. , , , , , if .


, Truffle Oracle Labs, SmallTalk , Newspeak Lisp . Lisp , .


结论


GraalVM — , , . , , , , .


GraalVM, http://www.graalvm.org/ . , , .


, , . , GraalVM @ChrisGSeaton @shelajev .


: Oleg Šelajev , Olya Gupalo Doug Simon

Source: https://habr.com/ru/post/zh-CN433432/


All Articles