JAVA基于ScriptEngineManager执行python、js脚本
1、用途
在一些复杂、可动态扩展项目中,常需要我们编写自定义脚本实现扩展功能,常见的脚本语言基于java、js、python。而ScriptEngineManager作为java脚本引擎,可编译、执行python、js等多种语言脚本,让脚本开发人员不再受限于某一种语言。
2、环境准备
安装jdk6+
引入jython2.7.2,推荐通过阿里云仓库下载
方式一:
maven引入:
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.2</version>
</dependency>
方式二:
maven下载:https://repo1.maven.org/maven2/org/python/jython-standalone/2.7.2/jython-standalone-2.7.2.jar
方式三:
阿里云maven仓库下载:
https://maven.aliyun.com/mvn/search,自行搜索jython-standalone
3、实现
3.1、python
import time
def test():
time1 = time.time()
r = 50000
a = 0.0
for n in range(r):
for n in range(r):
a = a + 3.1415926
print("python def:" + str(time.time() - time1))
return a
if __name__ == "__main__":
time1 = time.time()
for n in range(5):
test()
print("python total:" + str(time.time() - time1))
输出结果(单次执行时间约138s):
python def:142.17352175712585
python def:140.04075837135315
python def:134.03722548484802
python def:134.20326328277588
python def:139.48010849952698
python total:689.9358775615692
3.2、js
function test() {
var start = new Date().getTime();
for (var i = 0; i < 5; i++) {
test1();
}
console.log("js total:" + (new Date().getTime() - start));
}
function test1() {
var start = new Date().getTime();
var r = 50000;
var a = 0.0;
for (var i = 0; i < r; i++) {
for (var j = 0; j < r; j++) {
a = a + 3.1415926;
}
}
console.log("js function:" + (new Date().getTime() - start));
}
输出结果(单次执行时间约2.9s):
js function:2986
js function:2766
js function:2791
js function:2931
js function:3030
js total:14506
3.3、java
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 5; i++) {
test();
}
System.out.println("java total:" + (System.currentTimeMillis() - start));
}
public static double test() {
long start = System.currentTimeMillis();
int r = 50000;
double a = 0.0;
for (int i = 0; i < r; i++) {
for (int j = 0; j < r; j++) {
a = a + 3.1415926;
}
}
System.out.println("java method:" + (System.currentTimeMillis() - start));
return a;
}
输出结果(单次执行时间约2.6s):
java method:2455
java method:2603
java method:2870
java method:2714
java method:2675
java total:13317
3.4、ScriptEngineManager
public static void main(String[] args) {
runJsScript();
runPythonScript();
}
public static void runJsScript() {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("javascript");
try (FileReader fr = new FileReader("test.js")) {
engine.eval(fr);
Invocable invoke = (Invocable) engine;
String val = (String) invoke.invokeFunction("test");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void runPythonScript() {
try (FileReader fr = new FileReader("test.py")) {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("python");
engine.eval(fr);
} catch (Exception ex) {
ex.printStackTrace();
}
}
python脚本输出结果(单次执行时间约72.4s):
python def:68.8059999943
python def:67.9090001583
python def:75.4129998684
python def:75.0740001202
python def:74.632999897
python total:361.842999935
js脚本输出结果(单次执行时间约6.2s):
js function:7049
js function:7014
js function:7033
js function:2775
js function:7034
js total:30906
4、执行效率
原生 | ScriptEngineManager | |
---|---|---|
java | 2.6s | - |
python | 138s | 72.4s |
js | 2.9s | 6.2s |
ScriptEngineManager编译python代码约耗时3-3.5s,且编译时间会随python代码量而增加
针对浮点数操作,ScriptEngineManager执行效率比python原生快近一倍
随后进行的字符串比对操作,python原生执行效率又比ScriptEngineManager快出近一倍
结论:
(1)ScriptEngineManager可实现跨语言的编译、运行
(2)针对python,ScriptEngineManager能提升部分代码执行效率
(3)如需考虑自定义脚本执行效率,推荐用java编写