JAVA基于ScriptEngineManager执行js、python脚本

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
java2.6s-
python138s72.4s
js2.9s6.2s

ScriptEngineManager编译python代码约耗时3-3.5s,且编译时间会随python代码量而增加
针对浮点数操作,ScriptEngineManager执行效率比python原生快近一倍
随后进行的字符串比对操作,python原生执行效率又比ScriptEngineManager快出近一倍

结论:
(1)ScriptEngineManager可实现跨语言的编译、运行
(2)针对python,ScriptEngineManager能提升部分代码执行效率
(3)如需考虑自定义脚本执行效率,推荐用java编写

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值