我在jCT的说明中提到,jCT为了保障速度,没有用正则。今天我特意改写了以正则解析模板代码,仅仅支持注释文法jCT3版本,测试一下Build过程(也就是主要的解析过程了)的速度差异。结果如下(数值为同样循环条件下所用时间,越小越好)
(AMD双核)
FireFox 3.0.1:
非正则版本: 75
正则版本: 300
IE 8:
非正则版本:140
正则版本: 470
Chrome :
非正则版本:140
正则版本: 470
下面是在另一台机器上(AMD单核),看相对值就行了
FireFox 3.0.1:
非正则版本:150
正则版本: 350
IE6 :
速度不稳定,比IE7慢,就不贴了
IE7 :
非正则版本:200
正则版本: 578
Chrome :
非正则版本:160
正则版本: 520
Safari 3.1:
非正则版本:110
正则版本: 422
Opera 9.52:
非正则版本:109
正则版本: 650
结果很明显呀,正则版本就是慢呀,同时贴出正则的版本,(此版本中增加了一个成员属性定义,非正则版本稍后更新)
并且我没有发现Chrome在字符串处理上的优势呀
jCT 第3版 正则注释风格版源码
/**
* JavaScript Common Templates(jCT) 3(第3版) 正则注释风格版
* http://code.google.com/p/jsct/
*
* licensed under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*
* Author achun (achun.shx at gmail.com)
* Create Date: 2008-9-9
* Last Date: 2008-9-9
* Revision:rc3.8.9.9
*/
function jCT(txt,path){//构建jCT对象,仅仅准备基础数据
this.Fn = new arguments.callee.Instance({txt:txt,path:path});
for (var i in this) this.Fn.Reserve+=','+i+',';
}
jCT.prototype={
Extend:function(jct){//扩展自己
for (var i in jct){
if(this[i] && this[i].Fn && this[i].Fn.JavaScriptCommonTemplates && this[i].Extend )
this[i].Extend(jct[i]);
else if(this.Fn.Reserve.indexOf(','+i+',')==-1)//防止保留成员被覆盖
this[i]=jct[i];
}
if(typeof jct.RunNow=='function') jct.RunNow.call(this);
return this;
},
ExecChilds:function(childs,exec){//执行childs对象所列成员里的某个方法,默认是Exec方法
exec=exec||'Exec';
for(var c in childs)
if(this[c] && (typeof this[c][exec]=='function'))
this[c][exec](childs[c]);
return this;
},
BuildChilds:function(childs){//构建子jCT对象,并执行RunNow
if(undefined==childs) childs=[];
var cs={};
for(var i=0;i<childs.length;i++) cs[childs[i]]=true;
for (var i in this)
if(this[i].Fn && this[i].Fn.JavaScriptCommonTemplates && (childs.length==0 || cs[i])){
this[i].Build();
if(typeof this[i].RunNow=='function') this[i].RunNow();
}
return this;
},
GetView:function(){return 'Invalid templates';},//得到装配数据后的视图,此方法会在Build的过程中重建
Build:function(){//构建实例
this.Fn.Build(this);
return this;
}
};
jCT.Instance=function(Options){
this.Src=Options.txt||'';
this.Src=this.Src.replace(this.RegClear,'');
this.Path=Options.path||'';
this.A=[];//由src转换的模板数组
this.V=[];//GetView执行的文本结果,以数组形式存放
this.EXEC=[];//生成的js代码的临时数组
};
jCT.Instance.prototype={
JavaScriptCommonTemplates:3.0,
Reserve:'',//保留成员
RegClear:/<!--clear([\w\W]*?)\/clear-->/g,
RegTrim:/^\s+|\s+$/g,
RegFun:/\/\*((?:(?!\*\/).)+)\*\//,
Reg:/(<!---|\+-)([\w\W]*?)(-->|-\+)/g,//comment风格的定义
Build:function(self){
this.Pos=0;
this.EXEC=['this.Fn.V=[];'];
var ins=this;
try{
this.Src.replace(this.Reg,function(all,begin,code,end,pos){
return ins.Parse(all,begin,code,end,pos,self);
});
this.Push(this.Src.length,'return this.Fn.V.join("");');//最后一段
self.GetView=new Function(this.EXEC.join('\n'));
}catch (ex){
this.V=['jCT Parse Error'];
self.ERROR={message:ex.message + '\n'+ (ex.lineNumber || ex.number)};
}
if(self.RunNow)
self.RunNow();
},
Push:function(pos,code,exp){
if(pos<this.Pos) return;
var htm=this.Src.slice(this.Pos,pos).replace(this.RegTrim,'');
code=code.replace(this.RegTrim,'');
if(htm){
this.EXEC.push('this.Fn.V.push(this.Fn.A['+this.A.length+']);');
this.A.push(htm);
}
if(code) if(exp)
this.EXEC.push('this.Fn.V.push('+code+');');
else
this.EXEC.push(code);
},
Parse:function(all,begin,code,end,pos,self){
if(pos<this.Pos || this.Pos<0) return all;
var ins=this;
if(begin=='+-')//取值表达式+-???-+
this.Push(pos,code,true);
else{//语法块<!---???-->
var copy=code;
copy.replace(this.RegFun,function(text,fun,at){//成员语法/*???*/
ins.Push(pos,'');
ins.Pos=pos+all.length;
if(fun.slice(0,1)!='+'){//jCT成员语法开始+???
code='';
return '';
}
switch(fun.slice(1,2)){
case '@'://子模板开始
var name='<!---/*-'+fun.slice(1)+'*/-->';
ins.Pos=ins.Src.indexOf(name,pos+code.length);
if(ins.Pos>0){
self[fun.slice(2)]=new jCT(ins.Src.slice(pos+all.length,ins.Pos),ins.Path);
ins.Pos+=name.length;
}
break;
case '$'://成员对象
var val=code.slice(at+text.length).replace(ins.RegTrim,'');
var obj=new Function('return '+val+';');
self[fun.slice(2)]=obj.call(self);
break;
default://成员函数
self[fun.slice(1)]=new Function(code.slice(at+text.length));
break;
}
code='';
return '';
});
if(code) this.Push(pos,code);//普通javascript语句
}
if(this.Pos>=0 && code) this.Pos=pos+all.length;
return all;
}
};
本文对比了使用正则表达式与非正则表达式的jCT模板引擎在不同浏览器下的构建速度。结果显示,在所有测试环境中,非正则版本的构建速度明显优于正则版本。
264

被折叠的 条评论
为什么被折叠?



