【发布时间】:2017-10-03 19:12:50
【问题描述】:
我有一个依赖于 ruby 脚本结果的 Java 应用程序。我面临的问题是这个 ruby 脚本被多次调用,每次执行时都需要加载脚本的库。
我不熟悉 Ruby,但在搜索中我遇到了 JRuby。因为它解释了 ruby 代码并在 JVM 上运行,所以我最初的想法是“太好了,我可以将 ruby 脚本编译为 .class 文件将其打包并像常规 java 对象一样与它交互”。这将避免每次执行 ruby 脚本时加载库所带来的开销。
在深入研究了 jruby 之后,我了解到它不能以这种方式工作。所以要做我想做的事,我可以使用 JRuby 的 JavaEmbedUtils 来
- 使用我的 Ruby 脚本加载 Ruby 运行时对象
- 创建一个基本上知道如何处理和响应我的脚本的接收器对象。
- 从脚本调用所需的方法。
这是我的想法(我很快就会测试)
// 1
List<String> paths = new ArrayList<>();
paths.add(".");
Ruby runtime = JavaEmbedUtils.initialize(paths);
// 2
String script = "/path/to/script.rb";
IRubyObject recvr = JavaEmbedUtils.newRuntimeAdapter().eval(runtime, script);
// 3 Call this many times
JavaEmbedUtils.invokeMethod(runtime, receiver, "method", null, null);
我的理解是否正确,因为这种方法允许我在加载脚本库一次的同时多次使用脚本的内容?是否有替代或更多的 JRuby 方式来做我正在寻找的事情?
更新
所以我测试了类似于 Eugene 建议的东西 (a),即 ScriptingContainer,并将其与使用 (b) java.lang.Runtime 调用脚本进行了比较,总共运行了 30 次。
- 平均而言,(a) 大约快 8 倍 (b)
- 初始化 (a) 的运行时间大约需要 7 秒
- (a) 和 (b) 的初始运行时间比后续运行时间长 40 倍和 150-250 倍。
- (a) 的初始运行速度比 (b)s 快 11 倍
【问题讨论】:
-
答案已更新。