我们经常看到人们出于各种目的而使用脚本(例如,在服务任务,执行侦听器等中)。 使用脚本和Java逻辑通常很有意义:
- 它不需要打包到jar中并放在classpath上
- 它使流程定义更易于理解:无需查看其他文件
- 逻辑是流程定义的一部分,这意味着无需费劲就能确保使用了正确的逻辑版本
但是,重要的是还要牢记在流程定义中使用脚本的性能方面,并在这些需求与上述好处之间取得平衡。
我们通常会看到与Activiti一起使用的两种脚本语言是Javascript和Groovy。 Javascript与JDK(用于JDK 6和7的Rhino )和用于JDK 8的Nashorn捆绑在一起。 对于Groovy,需要将Groovy脚本引擎添加到类路径。
但让我告诉你,我没有使用JavaScript作为脚本语言的选择风扇,因为有JDK版本之间移动时(在以前的文章中我读更多微妙的变化在这里和这里 ,以及这些都是人的那些记录...)。 因此,这意味着您可以在一天之内编写自己的逻辑,并且一切都可以愉快地工作,而在JDK升级后的第二天,这一切都会失败。 我宁愿花时间在实际编码上。
为了验证性能,我做了一个非常小的基准测试:
以及脚本在哪里做了类似的愚蠢的事情(关键是在那里有一个getVariable()和setVariable()以及一些诸如获取当前日期的额外内容):
var input = execution.getVariable(‘input’);
var today = new Date().getDay();
execution.setVariable(‘result’, input * today);
Java服务任务中的相同代码:
public class MyDelegate implements JavaDelegate {@Overridepublic void execute(DelegateExecution execution) throws Exception {Integer input = (Integer) execution.getVariable("input");int today = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);execution.setVariable("result", input * today);}
}
和Groovy对应的:
def input = execution.getVariable('input');
int today = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
execution.setVariable('result', input * today);
我启动了该流程实例10.000次,并记下了总执行时间,我认为这些数字说明了一切:
- JavaDelegate :6255毫秒
- Groovy :7248毫秒
- Javascript :27314毫秒
使用的JDK版本是最新版本(1.8.0_60)。 第一次运行测试时,我是在1.8.0_20上运行的,而Javascript结果则提高了25%(我发现JDK 1.8.0_40的性能得到了提高)。 对于Groovy,我使用的是2.4.4版本(您应该使用该版本,因为较旧的版本存在安全问题 !)
只是为了给出选项之间的区别的直观印象:
与使用Javascript相比,使用Groovy作为脚本语言似乎是更好的性能选择。 一定要考虑到这是一个非常简单的用例的微基准。 但是,鉴于过去使用JDK升级会破坏Javascript脚本的麻烦以及这种结果,默认情况下很难选择Javascript。
15年9月11日更新:不少人问我为什么差异如此之大。 我的假设是,这是因为JDK中的javascript引擎不是线程安全的,因此无法重用或缓存,因此每次启动ScriptingEngine的成本很高。 如果您看一下http://docs.oracle.com/javase/7/docs/api/javax/script/ScriptEngineFactory.html ,您会看到有一个特殊的参数THREADING,我们在Activiti中使用它: https ://github.com/Activiti/Activiti/blob/master/modules/activiti-engine/src/main/java/org/activiti/engine/impl/scripting/ScriptingEngines.java#L111确定脚本引擎是否可以已缓存。 Nashorn(和Rhino)在此处返回null,这意味着它不能用于在多个线程上执行脚本,即每个线程需要它自己的实例。 我只能假定JDK中的ScriptEngineManager做类似的事情。
翻译自: https://www.javacodegeeks.com/2015/09/the-performance-impact-of-scripting-in-processes.html