Aviator——轻量级表达式执行引擎
Upcoming SlideShare
Loading in...5
×
 

Aviator——轻量级表达式执行引擎

on

  • 5,179 views

Aviator——轻量级表达式执行引擎,介绍和示例

Aviator——轻量级表达式执行引擎,介绍和示例

Statistics

Views

Total Views
5,179
Views on SlideShare
2,651
Embed Views
2,528

Actions

Likes
1
Downloads
40
Comments
0

8 Embeds 2,528

http://www.blogjava.net 2510
http://www.zhuaxia.com 6
http://reader.youdao.com 3
http://cache.baidu.com 3
http://xianguo.com 2
http://cache.baiducontent.com 2
http://blogjava.net 1
http://translate.googleusercontent.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Aviator——轻量级表达式执行引擎 Aviator——轻量级表达式执行引擎 Presentation Transcript

  • Aviator——飞行家
    轻量级的表达式执行引擎
    伯岩(boyan@taobao.com)
  • 提纲
    起源
    语言
    性能
    结语
  • 起源
    Notify引入AMP订阅模型,支持header表达式匹配
    类似JMS规范的selector机制,通过表达式过滤消息。
    Notify在服务端,JMS selector在客户端
    第一个版本使用groovy
    优点:groovy是图灵完备的语言,淘宝内部使用较多,用户相对熟悉
    缺点: groovy-all打包引用的依赖库太多,太大。Notify并不需要一门完整的语言。
  • 起源
    初步设想实现一个表达式引擎
    基于ASM动态编译生成字节码,并交给JVM执行。
    非图灵完备,对java语法剪裁
    没有赋值,没有位运算,没有条件语句(除了三元运算符),没有循环语句
    仅支持逻辑运算、算术运算、正则匹配、函数调用和三元表达式
  • 起源
  • 项目信息
    名称:Aviator(飞行家)
    主页:http://code.google.com/p/aviator/
    协议:LGPL
    大小: 403K (包括asm)
    Groovy 1.6.4 (4.3M,不包括依赖包)
    其他信息
    单元测试覆盖率 90.1%
    LOC:14000+
    Classes: 131
  • 语言
    AviatorEvaluator 入口类
    AviatorEvaluator.execute()
    AviatorEvaluator.execute(env)
    env为表达式中变量的值
    env为Map<String,Object>
    AviatorEvaluator.compile(string)
    AviatorEvaluator.compile(string,cached)
    cached 是否缓存编译结果
  • Hello world
    String name= args[0];
    Map<String, Object> env = new HashMap<String, Object>();
    env.put(" name ", name);
    String result = (String) AviatorEvaluator.execute(" 'hello ' + name ", env);
    System.out.println(result);
  • 数据类型
  • 算术运算
    1+2+3
    6-3+4
    6-(3+4)
    1*2*3+1/2/3+100%3
    (1+2/(3-4)*pi-2*pi*r+pi/j*i%100
  • 逻辑运算和关系运算
    true
    false && true
    true || false
    短路规则
    messageType==‘trade-cteate’ && !committed
    !bool
    a>b
    a>=nil , 永远返回true
    a<b
    a<=nil ,返回false,除非a为nil
    a==b
    a!=nil
  • 三元操作符 ?:
    1>0? 1:-1
    bool? (a+b) : (a-b)
    !t? i>0? f:ch : f>3?email:ch
    多层嵌套
    !t? (i>0? f:ch) :( f>3?email:ch)
    使用括号
  • 正则匹配
    类Perl,Ruby的匹配语法,匹配成功返回true,否则返回false
    正则表达式语法与Java相同
    匹配成功,分组存入$digit的变量中,后续可获取
    '10'=~/^+$/
    'ABC'=~/^[A-Za-z]+$/
    '<html>hello</html>'=~/<(.*)>.*<>|<(.*) >/
    email=~/([0-8]+)@+[+]+/ ? $1:'unknow‘
    $1 指向匹配的第一个分组,也就是用户名
    $0 指向整个匹配的字符串
  • 字符串运算
    ‘hello’+1 == ‘hello1’
    ‘hello ’ + ‘world’ == ‘hello world’
    ‘hello ’ + nil == ‘hello null’
    i+’hello’ == i.toString() + ‘hello’
    任何对象与String相加,结果为String
    ‘abc’ > ‘bac’
    ‘abc’ ==‘abc’
    字符串比较可以直接使用关系运算符
    date > '2009-12-20 00:00:00:00‘
    字符串可以跟java.util.Date直接比较,字符串形式必须为yyyy-MM-dd HH:mm:ss:SS
  • 访问数组、List和Map
    通过[]可直接访问数组或者java.util.List中的元素
    a[0]
    list[0]-a[1]*list[1]
    java.util.Map可以通过map.key的形式访问Map中key对应的value
    property.long
    property.short
  • 变量的嵌套访问
    foo.bar.i
    变量foo中的bar字段中的i字段的属性值
    foo.date.year
    foo.date.month
    变量foo中的java.util.Date对象的year值和month值
    这是利用cmmons-beanutils反射
  • 函数调用
    sysdate()
    rand()
    println(a) print(a)
    string.contains(‘hello’,’ell’)
    string.length(a)
    math.pow(3,2.0)
    math.sin(30)
    ……etc,目前有system、math和seq三种标准库函数
  • Seq库
    java.util.Collection子类及数组称为seq集合
    count(seq)
    include(seq,element)
    sort(seq)
    返回新的seq,原来的seq不变
    map(seq,fun)
    reduce(seq,fun,init)
    filter(seq,fun)
    返回新的seq,原来的seq不变
  • Seq库
    map(s,println)
    map(s,-) 求相反数组成的集合
    filter(s,seq.gt(3)) value>3组成的集合
    filter(s,seq.exists()) 非nil组成的集合
    reduce(s,+,0) 求和
    reduce(s,*,1) 阶乘
    include(s,’hello’)
  • 自定义函数
    class AddFunction implements AviatorFunction
    自定义函数实现AviatorFunction接口
    public AviatorObject call(Map<String, Object> env, AviatorObject... args)
    实际的调用操作,args为传入的参数
    public String getName()
    返回函数名,表达式使用该名称
    AviatorEvaluator.addFunction(new AddFunction());
    注册函数
    AviatorEvaluator.execute("add(1,2)"));
    AviatorEvaluator.execute("add(add(1,2),100)"));
  • 类型转换规则
    Java的byte short int long都转化为Long类型,Java的float,double都将转化为Double类型。Java的char String都将转化为String。Java的null都将转为nil。
    当两个操作符都是Double或者都是Long的时候,各自按照Double或者Long的类型执行
    当两个操作符中某一个是Double的时候,另一个操作数也将转换成Double,按照Double类型执行。
    任何类型与String相加,结果为String
    任何类型都比nil大,除了nil本身。
    nil在打印或者与字符串相加的时候,显示为null
    形如"yyyy-MM-dd HH:mm:ss:SS"的字符串,在与java.util.Date做比较的时候将尝试转换成java.util.Date对象比较。
    没有规定的类型转换操作,除了未知的变量类型之间,都将抛出异常。
  • 两种模式
    编译速度优先
    AviatorEvaluator.setOptimize(AviatorEvaluator.COMPILE)
    运行效率优先
    AviatorEvaluator.setOptimize(AviatorEvaluator.EVAL)
  • 性能
    测试场景
    不同表达式在不同引擎执行1000万次的时间。
    预热
    预先编译,再执行
    部分测试的表达式OGNL抛出异常
    测试引擎
    Groovy 1.6.4
    MVEL 2.0.17
    Aviator(运行速度优先) 1.0.0-final
    OGNL 2.7.1
  • 1000+100.0*99-(600-3*15)%(((68-9)-3)*2-100)+10000%7*71
  • i * pi + (d * b - 199) / (1 - d * pi) - (2 + 100 - i / pi) %
  • 'A' == 'A' || 'B' == 'B' && 'ABCD' == t &&  'A' == 'A'
  • i>pi || !bool || d+pi*i>1000 && b<0
  • thiz.vars.i+100-(thiz.vars.bool?thiz.vars.d:thiz.vars.pi)-(thiz.vars.d+thiz.vars.pi)+t
  • 小结
    Aviator在编译执行常量组成的表达式非常快速,直接在编译阶段执行出结果。
    Aviator的算术运算性能还不错,考虑到它做了不少类型转换的工作。
    Aviator的关系运算和逻辑运算的效率较低,这是未来需要改进的地方。
    总体来讲,Aviator的效率介于groovy和mvel之间,ognl新版本仍然有不少BUG。
  • Summary
    轻量级
    字节码生成
    支持算术、逻辑和关系运算
    支持三元表达式
    支持语言层面的正则匹配
    函数调用和自定义函数
    函数式的集合访问和操作
    性能满足要求