读书人

QLExpress脚本语言技术讲授(6)-QLEx

发布时间: 2012-09-11 10:49:03 作者: rapoo

QLExpress脚本语言技术讲解(6)-------QLExpress的缓存管理

(注:相关代码请参考 com.ql.util.express.test.ExpressCacheTest类,

QLExpress 源代码下载地址:http://code.taobao.org/p/QLExpress/src/ )

1、QLExpress的缓存带来的好处:

自带了一个本地缓存,用于缓存指令集,已减少编译阶段的时间消耗。

?

@Testpublic void testScriptCache() throws Exception {runner.addMacro("计算平均成绩", "(语文+数学+英语)/3.0");IExpressContext<String, Object> context =new DefaultContext<String, Object>();context.put("语文", 88);context.put("数学", 99);context.put("英语", 95);long times =10000;long start = new java.util.Date().getTime();while(times-->0){calulateTask(false, context);}long end = new java.util.Date().getTime();echo("不做缓存耗时:"+ (end-start) +" ms");times =10000;start = new java.util.Date().getTime();while(times-->0){calulateTask(true, context);}end = new java.util.Date().getTime();echo("做缓存耗时:"+ (end-start) +" ms");}private void echo(Object obj){System.out.println(obj);}private void calulateTask(boolean isCache, IExpressContext<String, Object> context) throws Exception{runner.execute("计算平均成绩", context, null, isCache, false);}

?

实验结果:效果是非常明显的!

不做缓存耗时:890 ms做缓存耗时:22 ms

?

?

?

2、ExpressRunner 自带的缓存

在同一个ExpressRunner执行器内是全局的,脚本间也可以相互调用,非常的强大。

适用场景:业务逻辑非常复杂,但是全局统一,业务逻辑需要很高的复用性。

?

@Testpublic void testLocalCacheMutualImpact()throws Exception {//缓存在本地的脚本都是全局的,可以相互调用runner.addMacro("计算平均成绩", "(语文+数学+英语)/3.0");runner.addMacro("是否优秀", "计算平均成绩>90");IExpressContext<String, Object> context =new DefaultContext<String, Object>();context.put("语文", 88);context.put("数学", 99);context.put("英语", 95);echo(runner.execute("是否优秀", context, null, false, false));}


3、独立于ExpressRunner的外部缓存处理器

适用场景:业务逻辑相对简单,脚本只依赖系统函数,不相互依赖,需要比较高的脚本隔离性和安全性,避免相互影响。

?

@Testpublic void testRemoteCache(){//数据的预先加载ExpressRunner runner =new ExpressRunner();ExpressRemoteCacheRunner cacheRunner = new LocalExpressCacheRunner(runner);cacheRunner.loadCache("计算平均成绩", "(语文+数学+英语)/3.0");cacheRunner.loadCache("是否优秀", "计算平均成绩>90");IExpressContext<String, Object> context =new DefaultContext<String, Object>();context.put("语文", 88);context.put("数学", 99);context.put("英语", 95);//ExpressRemoteCacheRunner都只能执行自己原有的脚本内容,而且相互之间隔离,保证最高的脚本安全性echo(cacheRunner.execute("计算平均成绩", context, null, false, false, null));try{echo(cacheRunner.execute("计算平均成绩>90", context, null, false, false, null));}catch(Exception e){echo("ExpressRemoteCacheRunner只支持预先加载的脚本内容");}try{echo(cacheRunner.execute("是否优秀", context, null, false, false, null));}catch(Exception e){echo("ExpressRemoteCacheRunner不支持脚本间的相互调用");}}

?

总结下:

1、缓存主要是将 文本-》生成指令集 这个过程缓存起来,所以ExpressRunner的编译执行的,但是编译过程又属于表达式类型脚本,只要符合定义的语法规范即可。

2、ExpressRunner自带的缓存会全局保存,每一次脚本执行的时候可以依赖到以前的指令。

3、ExpressRemoteCacheRunner每一次load脚本的时候,只将本次编译好的指令集缓存起来,可以放在本地也可以放入远程的缓存系统中(如淘宝的 tair 等),所以牺牲了复用性,得到了安全性和独立性。

?

读书人网 >编程

热点推荐