博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
轻量级高性能的表达式求值器——aviator发布2.0
阅读量:6672 次
发布时间:2019-06-25

本文共 1962 字,大约阅读时间需要 6 分钟。

    是一个轻量级的、高性能的Java表达式求值器,主要应用在如工作流引擎节点条件判断、MQ中的消息过滤以及某些特定的业务场景。

    自从上次发布1.0后,还发过1.01版本,不过都没怎么宣传。这次发布一个2.0的里程碑版本,主要改进如下:

1、完整支持位运算符,与java完全一致。位预算符对实现bit set之类的需求还是非常必须的。

2、性能优化,平均性能提升100%,函数调用性能提升200%,最新的与groovy和JEXL的性能测试看这里

3、添加了新函数,包括long、double、str用于类型转换,添加了string.indexOf函数。

4、完善了用户手册,更新性能测试。

 

下载地址: 

项目主页: 

用户指南: 

性能报告: 

源码:         

 

Maven引用(感谢许老大的帮助):

    
<
dependency
>
            
<
groupId
>
com.googlecode.aviator
</
groupId
>
            
<
artifactId
>
aviator
</
artifactId
>
                        
<
version
>
2.0
</
version
>
    
</
dependency
>

     这个项目目前用在我们的MQ产品中做消息过滤,也有几个公司外的用户告诉我他们也在用,不过估计不会很多。有这种需求的场景还是比较少的。这个项目实际上是为我们的MQ定制的,我主要想做到这么几点:

(1)控制用户能够使用的函数,不允许调用任何不受控制的函数。

(2)轻量级,不需要嵌入groovy这么大的脚本引擎,我们只需要一个剪裁过的表达式语法即可。

(3)高性能,最终的性能在某些场景比groovy略差,但是已经非常接近。

(4)易于扩展,可以容易地添加函数扩展功能。语法相对固定。

(5)函数的调用避免使用反射。因此没使用dot运算符的函数调用方式,而是更类似c语言和lua语言的函数调用风格。函数是一等公民,seq库的风格很符合我的喜好。

  seq这概念来自clojure,我将实现了java.util.Collection接口的类和数组都称为seq集合,可以统一使用seq库操作。例如假设我有个list:

        Map
<
String, Object
>
 env 
=
 
new
 HashMap
<
String, Object
>
();
        ArrayList
<
Integer
>
 list 
=
 
new
 ArrayList
<
Integer
>
();
        list.add(
3
);
        list.add(
100
);
        list.add(
-
100
);
        env.put(
"
list
"
, list);
   可以做这么几个事情,度量大小:
count(list)
   判断元素是否存在:
include(list,
3
)
   过滤元素,返回大于0的元素组成的seq:
filter(list,seq.gt(
0
))
   对集合里的元素求和,应用reduce:
reduce(list,
+
,
0
)
   遍历集合元素并打印:
map(list,println)
   最后,你还可以排序:
sort(list)
    这些函数类似FP里的高阶函数,使用起来还是非常爽的。
    对函数调用的优化,其实只干了一个事情,原来函数调用我是将所有参数收集到一个list里面,然后再转成数组元素交给AviatorFunction调用。这里创建了两个临时对象:list和数组。这其实是没有必要的,我只要在AviatorFunction里定义一系列重载方法,如:
   
public
 AviatorObject call(Map
<
String, Object
>
 env);
    
public
 AviatorObject call(Map
<
String, Object
>
 env, AviatorObject arg1);
    
public
 AviatorObject call(Map
<
String, Object
>
 env, AviatorObject arg1, AviatorObject arg2);
    
public
 AviatorObject call(Map
<
String, Object
>
 env, AviatorObject arg1, AviatorObject arg2, AviatorObject arg3);
    

   就不需要收集参数,而是直接invokeinterface调用AviatorFunction相应的重载方法即可。我看到在JRuby和Clojure里的方法调用都这样干的。过去的思路走岔了。最终也不需要区分内部的method和外部的function,统一为一个对象即可,进一步减少了对象创建的开销。

文章转自庄周梦蝶  ,原文发布时间 2011-07-13

转载地址:http://tnmxo.baihongyu.com/

你可能感兴趣的文章
使用Notepad++实现批量将ANSI转成为UTF-8编码
查看>>
Codeforces Round #280 (Div. 2) E. Vanya and Field 思维题
查看>>
HDU 1004 Let the Balloon Rise【STL<map>】
查看>>
Java千百问_05面向对象(006)_is-a,has-a,like-a是什么
查看>>
【Python】python更新数据库脚本两种方法
查看>>
linux进程同步机制_转
查看>>
PHP框架认识初步
查看>>
给 Android 初学者的 Gradle 知识普及
查看>>
分模块开发创建Action子模块——(九)
查看>>
基于Nginx实现一个自己的HTTP模块
查看>>
LeetCode(34)-Palindrome Number
查看>>
阅读《Android 从入门到精通》(24)——切换图片
查看>>
SimpleDateFormat线程不安全及解决的方法
查看>>
Unity---------Mesh理解
查看>>
hdu 1728 逃离迷宫 bfs记转向
查看>>
一分钟学会 ConstraintLayout 之从属性角度理解布局
查看>>
线程 Timer TimerTask 计时器 定时任务 MD
查看>>
[js高手之路]原型式继承与寄生式继承
查看>>
MBR分区操作-增加、扩展、删除
查看>>
php如何互换一个数组的首尾元素 中间不变 首尾互换
查看>>