Updates:2010-6-4
今天看到Wait也写了个时间测试代码程序,就回过头来看看自己曾经写的Watch对象代码,代码看起来有些丑陋了。修改了report方法,整合了下代码,使其简洁许多,去掉了一些不必要的创建DOM元素的操作,给report方法添加了个参数,用于确认把测试结果内容插入到哪个DOM元素里,默认是document.body,其他都没怎么修改。同时,这次修改也修改了一个小bug,就是在调用了report方法之后,没有清除原来的时间和结果内容。这样在页面中同时调用了几个report的时候,结果数据累加了。
最新版本:Watch_1_4.js。
=====================================================================
近段时间,由于需要测试很多代码的执行时间比较,测试代码需要重复编写,感觉很繁琐和机械化,所以就干脆封装了一个测试代码执行时间的对象—Watch。
Watch对象提供了start、stop、report、fns、execByTimes五个方法。顾名思义,start和stop是储存代码开始执行和结束时的时间,report方法用于显示测试结果。其他两个方法接下来会介绍,也都是非常简单的,目的都是用于简化测试代码的重复性编写,并且它可以很简单的嵌入到其他代码中。在使用Watch对象的时候需要引入Watch.js文件:<script type=”text/javascript” src=”Watch.js”></script>
一个简单的示例如下:
Watch.start("Cost times:");
for(var i=0;i<10000;i++){
document.createElement("iframe");
}
Watch.stop();
onload=function(){
//这句需要在onload事件中执行,因为需要插入DOM元素到document.body里。
Watch.report();
}
上面的示例的输出包括总时间,以及使用类似于进度条的形式来展示执行时间。《其他测试示例》、《TestLoop》
关于fns方法,它用于执行参数内的全部函数,并记录每个函数的执行时间。
Watch.fns(function(){
document.createElement("iframe");
},function(){
document.createElement("div");
}.......
}
execByTimes方法的功能跟fns类似,但是需要提供一个函数、一个时间执行次数times以及一个可选的参数title。如果你已经对重复编写for循环来执行某个函数或者一段用匿名函数封装的代码,这个方法将给你提供这方面的便利。
Watch.execByTimes(function(){
document.createElement("iframe");
},10000,"Create iframe Element");
上面讲述了Watch五个方法的使用方式,我是从中感受到了便利的。^_^
《下载Watch对象源码文件》或者《直接查看源码》
var Watch = {
result: [],
guid: -1,
totalTime: 0,
start: function(title){
this.result[++this.guid] = [title || this.guid, new Date().getTime()];
},
stop: function(){
var r = this.result[this.guid];
var t = new Date().getTime() - r[1];
this.totalTime += t;
r[1] = t;
},
report: function(){
this.guid = -1; //复原,重新开始计数
var div = document.createElement("div");
div.style.fontSize="12px";
document.body.appendChild(div);
var str = [];
str.push("<p><b>The total times:</b><span style='color:#f00'>"+this.totalTime+"</span> ms.</p>");
for (var i = 0, l = this.result.length; i < l; i++) {
var temp=document.createElement("div");
var span = document.createElement("span");
var inner_span = document.createElement("span");
temp.appendChild(span);
span.appendChild(inner_span);
span.style.width="200px";
span.style.display="inline-block";
span.style.backgroundColor="#eee";
inner_span.style.backgroundColor = "#f00";
inner_span.style.width = parseInt(200 * this.result[i][1] / this.totalTime) + "px";
inner_span.style.display="inline-block";
inner_span.innerHTML=this.result[i][1];
str.push("<p><span style='width:150px; display:inline-block;'>" + this.result[i][0] + ":</span> "+temp.innerHTML+"</p>");
temp=null;
span=null;
inner_span=null;
}
div.innerHTML = str.join("");
},
fns:function(){
var a=arguments;
for(var i=0,l=a.length;i<l;i++){
this.start();
a[i]();
this.stop();
}
},
execByTimes:function(fn,times,title){
this.start(title);
while(times--){
fn();
}
this.stop();
}
}
////////////////////////// 2010-01-28 updates////////////////////////////
由于考虑到在使用Watch测试的过程中,需要在页面上打印一些说明性的信息,所以Watch对象增加了print的方法,示例可以浏览这个页面:《测试页面》。
同时,Watch对象也修改了部分功能,最新修改版本:Watch_1_1.js
////////////////////////// 2010-01-29 updates////////////////////////////
这次修正了fns方法之前没有设置title的参数,所以重写了fns的实现方式:
fns: function(){
var a = arguments;
for (var i = 0, l = a.length; i < l; i++) {
this.start(a[i][0]);
a[i][1]();
this.stop();
}
}
fns方法内的参数不再是每一个函数,而是一个个数组,数组里第一个是title,第二个是函数,示例如下:
Watch.fns(["Normal",function(){
......
}],["Special",function(){
......
}]);
最新修改版本:Watch_1_2.js
////////////////////////// 2010-01-30 updates////////////////////////////
这次修正了当循环次数少的时候在IE下抛出“参数错误”的异常,同时加入了如果Javascript代码执行时间超过10s,就弹出提示框。虽然IE,FF,Google Chrome,Safari有内置了这个功能,可是Opera却没有。
最新修改版本:Watch_1_3.js