`
express_wind
  • 浏览: 29743 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

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

阅读更多

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

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

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

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

 

	@Test
	public 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执行器内是全局的,脚本间也可以相互调用,非常的强大。

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

 

	@Test
	public 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的外部缓存处理器

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

 

	@Test
	public 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 等),所以牺牲了复用性,得到了安全性和独立性。

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics