java表达式运算性能比较:Jep与QLExpress

原创 2021-11-18 09:48 阅读(2246)次

前言

之前我有分享过java的表达式运算,由于我的业务要求表达式中要有业务变量,例如要根据id和orderNumber动态生成一个单号,表达式的定义如下所示:
id+orderNumber
所以我们需要一个支持替换变量的表达式计算引擎,开始我们选择了jep,但后面发现我们业务中的jep表达式计算秒级只能做到2300条左右,这太慢了,于是我再找了下其他引擎,发现阿里开源了一个,名叫QLExpress,地址:https://gitee.com/cuibo119/QLExpress

上手试一下,引入maven:

  1. <dependency>
  2. <groupId>com.alibaba</groupId>
  3. <artifactId>QLExpress</artifactId>
  4. <version>3.2.0</version>
  5. </dependency>

表达式计算代码如下:

  1. public static void main(String args[]) throws Exception {
  2. ExpressRunner expressRunner = new ExpressRunner();
  3. String expressValue = "a+b";
  4. DefaultContext<String, Object> context = new DefaultContext<String, Object>();
  5. context.put("a",1);
  6. context.put("b",10);
  7. Object result = expressRunner.execute(expressValue, context, null, true, false);
  8. String value = result.toString();
  9. System.out.println(value);
  10. }

上面代码输出如下:

  1. 11

于是我赶紧拿它与jep做性能比较:
运行jep请参考我之前的文章:http://www.classinstance.cn/detail/168.html

jep做30000次运算

代码如下:

  1. public static void main(String args[]) throws Exception {
  2. long t1 = System.currentTimeMillis();
  3. String expressValue = "a+b";
  4. for (int i = 0;i<30000;i++) {
  5. JEP jep = new JEP();
  6. jep.addVariableAsObject("a",1);
  7. jep.addVariableAsObject("b",10);
  8. jep.parseExpression(expressValue);
  9. String value = jep.getValueAsObject().toString();
  10. System.out.println(value);
  11. }
  12. long t2 = System.currentTimeMillis();
  13. System.out.println("用时:"+(t2-t1));
  14. }

用时:2736

QLExpress做30000次运算

  1. public static void main(String args[]) throws Exception {
  2. long t1 = System.currentTimeMillis();
  3. ExpressRunner expressRunner = new ExpressRunner();
  4. String expressValue = "a+b";
  5. for (int i = 0;i<30000;i++) {
  6. DefaultContext<String, Object> context = new DefaultContext<String, Object>();
  7. context.put("a",1);
  8. context.put("b",10);
  9. Object result = expressRunner.execute(expressValue, context, null, true, false);
  10. String value = result.toString();
  11. System.out.println(value);
  12. }
  13. long t2 = System.currentTimeMillis();
  14. System.out.println("用时:"+(t2-t1));
  15. }

用时:879

结论

很明显示QLExpress比jep快了3倍多,为什么?因为QLExpress上面的代码开启了表达式缓存,不需要每次计算都解析表达式,并且ExpressRunner做成单例,减少对象的对象的创建,但Jep好像不能这么做。在我们的业务中QLExpress比jep快了10倍,所以我们果断把jep改成了QLExpress。其实QLExpress还有很多好的特性等着我们去发现。