在实际项目开发中,表达式用来表达一定的比较、计算和逻辑关系,而对该表达式的计算涉及分词技术,通常会将表达式转换成一个后缀表达式方便计算机计算,在实现上可以使用栈来实现。Java中有较多的工具方便我们不自己解析表达式实现解决此类问题,以下是总结:
1、Java自带的ScriptEngine
ScriptEngine可以实现Java和js脚本的互相调用,核心在于ScriptEngine和Bindings对象,后者用来绑定变量,并将和表达式一起发送给ScriptEngine从而完成计算结果。
ScriptEngineManager factory = new ScriptEngineManager();
engine = factory.getEngineByName("JavaScript");
ScriptContext newContext = new SimpleScriptContext();
engineScope = newContext.getBindings(ScriptContext.ENGINE_SCOPE);
binding(security);//绑定变量
boolean rs = (boolean) engine.eval(expression, engineScope);//eval方法获得计算结果
2、Google出品Aviator
Aviator是Google开源的表达式引擎,轻量级且运算速度快,突出的功能是表达式可以编译一次,多次执行,且表达式编译可以缓存,大大提高了速度。
Aviator对外暴露的是一个静态方法AviatorEvaluator.execute(expression, map),map用来绑定变量,expression是表达式串。
public boolean adjust(String expression, FullyFactor security, Map<String, Object> map) {
map.put("security", security);
return (boolean) AviatorEvaluator.execute(expression, map);
}
3、性能比较
实际项目测试中,一个6~7万的数据中执行一个表达式的检测,每条数据过一遍引擎。
ScriptEngine单例执行非常慢,耗时约15min,在经过创建8个ScriptEngine对象池的情况下,速度优化至11s无法降低。
同样业务背景,使用Aviator做同样的事情,采用表达式编译并缓存的情况下,同等资源下,初次过表达式仅需要4~7s,二次使用速度不超过3s。
网友评论