论坛首页 Java企业应用论坛

阿里巴巴开源平台新增项目SimpleEL

浏览 48000 次
该帖已经被评为良好帖
作者 正文
   发表时间:2011-04-08   最后修改:2011-04-15
Simple EL是一个表达式解析引擎。它将表达式解析分成四个部分:预处理、编译、缓存和执行。这四个步骤任意一部分都可以替换,类似设计模式中的Template Method。

说明,SimpleEL和JSTL中的EL没有任何关系,不要误会!

缺省的实现是:将表达式处理成Java Source,调用Tools.jar的Javac API动态编译,缓存变异后反射得到的实例,使得表达式的解析速度和Java静态编译的速度接近。

这是一个性能极致、扩展性良好的表达式解析引擎。

介绍项目的PPT:http://code.alibabatech.com/svn/SimpleEL/trunk/doc/SimpleEL.pptx

SVN:http://code.alibabatech.com/svn/simpleel
JIRA:http://code.alibabatech.com/jira/browse/simpleel
wiki:http://code.alibabatech.com/wiki/display/simpleel/Home

使用范例:
import com.alibaba.simpleEL.eval.DefaultExpressEvalService;
import com.alibaba.simpleEL.preprocess.DefaultVariantResolver.Type;

DefaultExpressEvalService service = new DefaultExpressEvalService();
service.regsiterVariant(int.class, "a", "b"); // 注册两个类型为Integer的变量

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", 3);
ctx.put("b", 4);

Assert.assertEquals(7, service.eval(ctx, "@a + @b"));
Assert.assertEquals(true, service.eval(ctx, "@a < @b"));


支持多行语句,包括if/else等等
DefaultExpressEvalService service = new DefaultExpressEvalService();
service.regsiterVariant(int.class, "a", "b"); // 注册两个类型为Integer的变量
service.setAllowMultiStatement(true); //设置支持多行语句

Map<String, Object> ctx = new HashMap<String, Object>();
ctx.put("a", 3);
ctx.put("b", 4);

Assert.assertEquals(1, service.eval(ctx, "if (@a > @b) { return @a - @b; } else {return @b - @a; }"));


调用java bean的方法进行过滤对象(复杂逻辑处理)
public static class Person {
	private int age;
	private String name;
	
	public Person(int age, String name) {
		this.age = age;
		this.name = name;
	}
	
	public int getAge() { return age; }
	public String getName() { return name; }
}

DefaultExpressEvalService service = new DefaultExpressEvalService();
service.setAllowMultiStatement(true);

// 注册变量p和list
service.regsiterVariant(Person.class, "p");  
service.regsiterVariant(List.class, "list");

List<Person> persons = new ArrayList<Person>();
persons.add(new Person(18, "吴能"));
persons.add(new Person(27, "刘芒"));
persons.add(new Person(40, "黄警"));
persons.add(new Person(50, "夏留"));

List<Person> list = new ArrayList<Person>();

for (Person p : persons) {
	Map<String, Object> ctx = new HashMap<String, Object>();
    ctx.put("p", p);
    ctx.put("list", list);
    service.eval(ctx, "if (@p.getAge() > 30) { @list.add(@p); } return null;");
}

Assert.assertEquals(2, list.size());

   发表时间:2011-04-08   最后修改:2011-04-08
这个理论上是最快的Java表达式解析引擎了,还没发现比SimpleEL更快的表达式解析引擎。可以吹牛是FastExpressEngine了   

阿里巴巴开源平台还会陆续增加一些优秀的项目,大家多多关注,多多支持!!

(之后的几天我很忙,下周末有空之后会补上性能测试报告)
0 请登录后投票
   发表时间:2011-04-08  
期待后续,没明白具体干什么用
0 请登录后投票
   发表时间:2011-04-08  
el 表达式 解析器...
如果别人不用el表达式,这个解析器不就没用了...混了,这市场不大
0 请登录后投票
   发表时间:2011-04-08  
http://code.alibabatech.com/svn/SimpleEL/trunk/src/main/java/com/alibaba/simpleEL/compile/CharSequenceCompiler.java

import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;


就这样?就这样?真的就这样?玩呢?alibaba?
0 请登录后投票
   发表时间:2011-04-08  
Bernard 写道
http://code.alibabatech.com/svn/SimpleEL/trunk/src/main/java/com/alibaba/simpleEL/compile/CharSequenceCompiler.java

import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;


就这样?就这样?真的就这样?玩呢?alibaba?


调用tools.jar动态编译啊,这有什么不妥?
0 请登录后投票
   发表时间:2011-04-08  
kanny87929 写道
el 表达式 解析器...
如果别人不用el表达式,这个解析器不就没用了...混了,这市场不大


都怪某人没帮我起一个好名字,此SimpleEL和jstl中的EL一点关系都没有。

SimpleEL是一个表达式解析引擎!
0 请登录后投票
   发表时间:2011-04-08  
没看懂
0 请登录后投票
   发表时间:2011-04-08  
性能测试:

import com.alibaba.simpleEL.eval.DefaultExpressEvalService;
import com.alibaba.simpleEL.preprocess.DefaultVariantResolver.Type;

public class SimpleELPerformanceTest extends TestCase {
	public void test_perf() throws Exception {
		DefaultExpressEvalService service = new DefaultExpressEvalService();
		service.regsiterVariant(Type.Integer, "a", "b", "c");

        Map<String, Object> ctx = new HashMap<String, Object>();
        ctx.put("a", 3);
        ctx.put("b", 4);
        ctx.put("c", 5);

        
        for (int i = 0; i < 10; ++i) {
        	perf(service, ctx);
        }
	}

	private void perf(DefaultExpressEvalService service, Map<String, Object> ctx) {
		long startMillis = System.currentTimeMillis();
		
		final int COUNT = 1000 * 1000;
        for (int i = 0; i < COUNT; ++i) {
        	service.eval(ctx, "(@a + @b) * @c");
        }
        
        long millis = System.currentTimeMillis() - startMillis;
        
        System.out.println("time : " + NumberFormat.getInstance().format(millis));
	}
}


测试环境:
引用
MacX Darwin Kernel Version 10.7.3 x86_64
CPU 2G Intel Core i7
java version "1.6.0_24"


测试结果:
引用
time : 614 // 第一次编译会稍慢
time : 52
time : 39
time : 39
time : 40
time : 39
time : 39
time : 38
time : 39
time : 39


从结果看来,执行这样的一个表达式(@a + @b) * @c,平均耗时39 nano,也就是一秒钟可以执行2500万次。
0 请登录后投票
   发表时间:2011-04-08  
EL不稀奇,最快的OGNL解析器,来一个?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics