如果我在 GraalVM 中从 Java 调用 R 代码(使用 GraalVM 的 polyglot 函数),R 代码和 Java 代码是否在同一个 Java 线程上运行(即操作系统或 Java 线程之间没有切换等?)另外,它是否相同“内存/堆”空间?也就是说,在下面的示例代码中(我取自https://www.baeldung.com/java-r-integration)
public double mean(int[] values) {
Context polyglot = Context.newBuilder().allowAllAccess(true).build();
String meanScriptContent = RUtils.getMeanScriptContent();
polyglot.eval("R", meanScriptContent);
Value rBindings = polyglot.getBindings("R");
Value rInput = rBindings.getMember("c").execute(values);
return rBindings.getMember("customMean").execute(rInput).asDouble();
}
调用是否rBindings.getMember("c").execute(values)
会导致值对象(整数数组)被复制?或者 GraalVM 是否足够聪明,可以将其视为指向同一内存空间的指针?如果是副本,复制时间是否与正常的 java clone() 操作相同(或相似,即在 20% 以内)时间?最后,调用 polyglot 函数(在本例中为 R 中实现的 customMean)是否与调用原生 Java 函数具有相同的开销?额外的问题:GraalVM JIT 编译器甚至可以跨层编译,例如说我有这个:
final long sum = IntStream.range(0,10000)
.stream()
.map(x -> x+4)
.map(x -> <<<FastR version of the following inverse operation: x-4 >>>)
.sum();
GraalVM 编译器是否会像普通的 Java JIT 编译器一样聪明,并意识到上面的整个语句可以在没有两个映射操作的情况下简单地编写(因为它们相互抵消)?
仅供参考:我正在考虑使用 GraalVM 来运行我的 Java 代码和我的 R 代码,一旦我在这里确定的问题得到解决(为什么 FASTR(即 GraalVM 版本的 R)与普通 R 相比要慢 10 倍*尽管 Oracle 声称40x *faster*?),其中一个动机是我希望消除从 Java 调用 R(使用 RServe())花费在网络 IO 上的 50% 时间(因为 Java 通过 TCP/IP 和 RServe 与 RServer 通信和Java在不同的线程和内存空间等)