高性能EL——Fel探秘,兼谈EL

  1. 云栖社区>
  2. 博客>
  3. 正文

高性能EL——Fel探秘,兼谈EL

沉默术士 2017-05-02 15:30:00 浏览981

Fel是最近javaeye比较火的关键词,这是由网友lotusyu开发的一个高性能的EL,从作者给出的数据来看,性能非常优异,跟前段时间温少开源的Simple EL有的一拼。首先要说,这是个好现象,国内的开源项目越来越多,可以看出开发者的水平是越来越高了,比如我最近还看到有人开源的类似kestel的轻量级MQ——fqueue也非常不错,有兴趣可以看下我的分析《fqueue初步分析》。

expression string -> antlr -> AST -> comiple -> java source template -> java class -> Expression 
FelEngine fel = new FelEngineImpl();
Expression exp 
= fel.comp
package com.greenpineyu.fel.compile;

import com.greenpineyu.fel.common.NumberUtil;
import com.greenpineyu.fel.Expression;
import com.greenpineyu.fel.context.FelContext;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;

public class Fel_0 implements Expression{

public Object eval(FelContext context) {
java.lang.Object var_1 
= (java.lang.Object)context.get(b); //
java.lang.Object var_0 = (java.lang.Object)context.get(a); //
return (ObjectUtils.toString(var_0))+(ObjectUtils.toString(var_1));
}

FelEngine fel = new FelEngineImpl();

Expression exp 
= fel.compile(a+bnull);
Map
<String, Object> env=new HashMap<String, Object>();
env.put(
a1);
env.put(
b3.14);
System.out.println(exp.eval(
new MapContext(env))); 

输出:

13.14 
com.greenpineyu.fel.exception.CompileException: package com.greenpineyu.fel.compile;

import com.greenpineyu.fel.common.NumberUtil;
import com.greenpineyu.fel.Expression;
import com.greenpineyu.fel.context.FelContext;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;

public class Fel_0 implements Expression{

public Object eval(FelContext context) {
java.lang.Object var_1 
= (java.lang.Object)context.get(b); //
java.lang.Object var_0 = (java.lang.Object)context.get(a); //
return (var_0)(var_1);
}
}

[Fel_0.java:
14: 运算符 不能应用于 java.lang.Object,java.lang.Object]
at com.greenpineyu.fel.compile.FelCompiler16.compileToClass(FelCompiler16.java:
113)
at com.greenpineyu.fel.compile.FelCompiler16.compile(FelCompiler16.java:
87)
at com.greenpineyu.fel.compile.CompileService.compile(CompileService.java:
66)
at com.greenpineyu.fel.FelEngineImpl.compile(FelEngineImpl.java:
62)
at TEst.main(TEst.java:
14)
Exception in thread 
main java.lang.NullPointerException
at TEst.main(TEst.java:
18
FelEngine fel = new FelEngineImpl();
fel.getContext().set(
a1);
fel.getContext().set(
b3.14);
Expression exp 
= fel.compile(a+bnull);
Map
<String, Object> env = new HashMap<String, Object>();
env.put(
a1);
env.put(
b3.14);
System.out.println(exp.eval(
new MapContext(env))); 
package com.greenpineyu.fel.compile;

import com.greenpineyu.fel.common.NumberUtil;
import com.greenpineyu.fel.Expression;
import com.greenpineyu.fel.context.FelContext;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;

public class Fel_0 implements Expression{

public Object eval(FelContext context) {
double var_1 = ((java.lang.Number)context.get(b)).doubleValue(); //
double var_0 = ((java.lang.Number)context.get(a)).doubleValue(); //
return (var_0)+(var_1);
}

可以看到这次将a和b都强制转为double类型了,做数值相加,结果也正确了:

4.140000000000001 

强类型还是弱类型,这是一个选择问题,如果你能在运行前就确定变量的类型,那么使用Fel应该可以达到或者接近于原生java执行的效率,但是失去了灵活性;如果你无法确定变量类型,则只能采用弱类型的EL。

EL涌现的越来越多,这个现象有点类似消息中间件领域,越来越多面向特定领域的轻量级MQ的出现,而不是原来那种大而笨重的通用MQ大行其道,一方面是互 联网应用的发展,需求不是通用系统能够满足的,另一方面我认为也是开发者素质的提高,大家都能造适合自己的轮子。从EL这方面来说,我也认为会有越来越多 特定于领域的,优点和缺点一样鲜明的EL出现,它们包含设计者自己的目标和口味,选择很多,就看取舍。

本文来源于"阿里中间件团队播客",原文发表时间" 2011-09-17"