单单上面这个例子,可以做成以下效率更高点,主要思路:尽量使用小单元,小循环<BODY> <SCRIPT LANGUAGE="JScript"> function ArrayJoin(){ var loHTML = new Array; for (var i=0; i<10000; i++){ loHTML[loHTML.length] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; } return loHTML.join(''); }function StringADD(){ var lsHTML = "",tmp="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for (var i=0; i<10000; i++){ lsHTML += tmp; } return lsHTML; }function StringADD2(){ var lsHTML = "",tmp="";; for (var i=0; i<100; i++)tmp+="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for (var i=0; i<100; i++)lsHTML += tmp; return lsHTML; }function StringADD3(){ var lsHTML = "",tmp="";; for (var i=0; i<10; i++)tmp+="1234567890"; for (var i=0; i<100; i++)lsHTML += tmp; return lsHTML.replace(/\d/g,"ABCDEFGHIJKLMNOPQRSTUVWXYZ"); }function SubmitEnter(){ var loStartDate = new Date(); var lsHTML = ArrayJoin(); var loEndDate = new Date(); alert(loEndDate-loStartDate+":"+lsHTML.length); var loStartDate = new Date(); var lsHTML = StringADD2(); var loEndDate = new Date(); alert(loEndDate-loStartDate+":"+lsHTML.length); var loStartDate = new Date(); var lsHTML = StringADD3(); var loEndDate = new Date(); alert(loEndDate-loStartDate+":"+lsHTML.length); } </SCRIPT> </HEAD><INPUT type=button onclick=SubmitEnter() value="submit"> </BODY>
我运行StringAdd()差点就挂了,StringAdd3()的效率确实很高
只是要循环多少次和tmp一次要加多少个数字以便以后替换的时候达到最佳效率怎么知道呢?
<BODY> <SCRIPT LANGUAGE="JScript"> function StringADD3(n){ var lsHTML = "",tmp="",t; for (t=Math.round(Math.sqrt(n)); t>0; t--)if(n%t==0)break; for (var i=0; i<t; i++)tmp+="1"; for (var i=0; i<n/t; i++)lsHTML += tmp; return lsHTML.replace(/\d/g,"ABCDEFGHIJKLMNOPQRSTUVWXYZ"); }function SubmitEnter(num){ var loStartDate = new Date(); var lsHTML = StringADD3(num); var loEndDate = new Date(); alert(loEndDate-loStartDate+":"+lsHTML.length/26); } </SCRIPT> </HEAD> <input type=text name=count value=6000> <INPUT type=button onclick=SubmitEnter(document.all.count.value) value="submit"> </BODY>
这是一个分析Array::join行为的例子 var calltime=0; var o= { toString:(function(){ calltime++; return "("+calltime+")["+Math.random()+"]"; }) } var a=new Array(); for(var i=0;i<10;i++)a[a.length]=o; alert(a.join("\n"));从显示的结果,可以猜到。Array::join的过程为: 1。分配另外一个数组arr1,数组元素的个数等于Array::length 2。把Array的所有元素的toString的最终字符串返回值都压到arr1中。 3。把所有的arr1的元素的长度都加起来得到tLength,然后分配长度为tLength*sizfof(WCHAR)的内存r1 4。把arr1的所有内容都用memcpy复制到r1的相应位置。 返回封装好的[r1]的string对象
中间加一个alert(a),表达效果更好点 <script>var calltime=0; var o= { toString:(function(){ calltime++; return "("+calltime+")["+Math.random()+"]"; }) } var a=new Array(); for(var i=0;i<10;i++)a[a.length]=o; alert(a); alert(a.join("\n"));</script>
看“性价比”最好的句子,呵呵 function ArrayADD3(n,str){ return new Array(parseInt(n)+1).join(str) } <BODY> var a=new Array(t+1) alert(a.join("1"))<SCRIPT LANGUAGE="JScript"> function ArrayADD3(n,str){ return new Array(parseInt(n)+1).join(str) }function SubmitEnter(num){ var loStartDate = new Date(); var lsHTML = ArrayADD3(num,"ABCDEFGHIJKLMNOPQRSTUVWXYZ"); var loEndDate = new Date(); alert(loEndDate-loStartDate+":"+lsHTML.length); } </SCRIPT> </HEAD> <input type=text name=count value=10000> <INPUT type=button onclick=SubmitEnter(document.all.count.value) value="submit"> </BODY>
效率更高的<BODY> <SCRIPT LANGUAGE="JScript"> function StringADD3(n){ var tmp,t; for (t=Math.round(Math.sqrt(n)); t>0; t--)if(n%t==0)break; tmp=ArrayADD3(t,"ABCDEFGHIJKLMNOPQRSTUVWXYZ") return ArrayADD3(n/t,tmp) } function ArrayADD3(n,str){ return new Array(parseInt(n)+1).join(str) } function SubmitEnter(num){ var loStartDate = new Date(); var lsHTML = StringADD3(num); var loEndDate = new Date(); alert(loEndDate-loStartDate+":"+lsHTML.length/26); } </SCRIPT> </HEAD> <input type=text name=count value=10000> <INPUT type=button onclick=SubmitEnter(document.all.count.value) value="submit"> </BODY>
更短,更快(累了,休息休息,呵呵) <BODY> <SCRIPT LANGUAGE="JScript"> function Repeat(str,n){ /************(qiushuiwuhen 2002-5-26)**************/ for (t=Math.round(Math.sqrt(n)); t>0; t--)if(n%t==0)break; var tmp=new Array(t+1).join(str) return new Array(n/t+1).join(tmp) } function SubmitEnter(num){ var loStartDate = new Date(); var lsHTML = Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ",parseInt(num)); var loEndDate = new Date(); alert(loEndDate-loStartDate+":"+lsHTML.length); } </SCRIPT> </HEAD> <input type=text name=count value=10000> <INPUT type=button onclick=SubmitEnter(document.all.count.value) value="submit"> </BODY>
呵呵,大开眼界了,别光是讨论字符窜,还有其它的,比如:<HTML> <BODY> <SPAN ID="inHTML"> </SPAN> <SCRIPT language=javascript> function inString(){ inHTML.innerHTML += "<SPAN>ABCD</SPAN>"; }function CreaElement(){ var loSpan = document.createElement("SPAN"); loSpan.innerHTML = "ABCD"; inHTML.appendChild(loSpan); }function test(){ inHTML.innerHTML = ""; var loStartDate = new Date(); var loHTML = new Array; for (var i=0; i<1000; i++){ loHTML[loHTML.length] = "<SPAN>ABCD</SPAN>"; } inHTML.innerHTML = loHTML.join(''); var loEndDate = new Date(); alert(loEndDate-loStartDate);
inHTML.innerHTML = ""; var loStartDate = new Date(); for (var i=0; i<1000; i++){ CreaElement(); } var loEndDate = new Date(); alert(loEndDate-loStartDate); inHTML.innerHTML = ""; var loStartDate = new Date(); for (var i=0; i<1000; i++){ inString(); } var loEndDate = new Date(); alert(loEndDate-loStartDate); } </SCRIPT> <input type="button" value="submit" onClick="test()"> </BODY> </HTML>还有例如创建 <Select> <TABLE> 等等, 如何能让它的效率更高,这样做的优缺点等等,应该应用在什么场合,希望看到高手的评论和思路...
同意lostinet(爱情 =∫[缘分∪友谊+浪漫]d永远) 观点!!!!!!!
to linhaibo(美洲豹):(差点晕倒,嘿嘿) 程序好和坏就在于执行效率,编写效率只是非编程人要求的
qiushuiwuhen(秋水无恨),好象是一个在说话哟,呵呵。 我只有学习了。
To: qiushuiwuhen(秋水无恨)现在的编程语言越来越先进,程序语言开发者已经替我们解决了很多的细节问题 我当然知道程序好和坏就在于执行效率,如果我们用的是汇编语言,就要对CPU,内存很熟悉.我想,使用JavaScript 没有必要去做上面讨论的那些事情吧!
在ArrayJoin中,
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
这字符串只出现一次,所以当你写loHTML[loHTML.length]时,系统只要分配一个指针指向该字符串即成,但用join时,系统只要算出返回字符串的总长度,然后拷贝字符串到该总字符串里的各个相应地址。这样,该函数的过程大概如下:
1000次分配一个指针,1次算总长度,1次分配内存,1000次拷贝(每次只拷贝26个字符,共拷贝26000个字符)但在第二种情形StringADD下则有所不同,因为每执行一次
lsHTML += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
系统需要重新分配内存,把原来的字符串拷贝过去,然后再把后面的字符串附加过去,这个分配内存,拷贝的过程是很费时的。说不定GC在这中间还会启动,那就更慢了。这样,该函数的过程大概如下:
1000次分配内存,1000次拷贝(每次拷贝都要拷贝以前的长度,26+2*26+3*26+大概要拷贝26*1000*1001/2=500*26000个字符!是上一个函数的500倍!)以上讨论中的数字只是近似,但量级应该是对的,别斤斤计较
<SCRIPT LANGUAGE="JScript">
function ArrayJoin(){
var loHTML = new Array;
for (var i=0; i<10000; i++){
loHTML[loHTML.length] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
}
return loHTML.join('');
}function StringADD(){
var lsHTML = "",tmp="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (var i=0; i<10000; i++){
lsHTML += tmp;
}
return lsHTML;
}function StringADD2(){
var lsHTML = "",tmp="";;
for (var i=0; i<100; i++)tmp+="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (var i=0; i<100; i++)lsHTML += tmp;
return lsHTML;
}function StringADD3(){
var lsHTML = "",tmp="";;
for (var i=0; i<10; i++)tmp+="1234567890";
for (var i=0; i<100; i++)lsHTML += tmp;
return lsHTML.replace(/\d/g,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}function SubmitEnter(){
var loStartDate = new Date();
var lsHTML = ArrayJoin();
var loEndDate = new Date();
alert(loEndDate-loStartDate+":"+lsHTML.length); var loStartDate = new Date();
var lsHTML = StringADD2();
var loEndDate = new Date();
alert(loEndDate-loStartDate+":"+lsHTML.length); var loStartDate = new Date();
var lsHTML = StringADD3();
var loEndDate = new Date();
alert(loEndDate-loStartDate+":"+lsHTML.length);
}
</SCRIPT>
</HEAD><INPUT type=button onclick=SubmitEnter() value="submit">
</BODY>
<SCRIPT LANGUAGE="JScript">
function StringADD3(n){
var lsHTML = "",tmp="",t;
for (t=Math.round(Math.sqrt(n)); t>0; t--)if(n%t==0)break;
for (var i=0; i<t; i++)tmp+="1";
for (var i=0; i<n/t; i++)lsHTML += tmp;
return lsHTML.replace(/\d/g,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
}function SubmitEnter(num){
var loStartDate = new Date();
var lsHTML = StringADD3(num);
var loEndDate = new Date();
alert(loEndDate-loStartDate+":"+lsHTML.length/26);
}
</SCRIPT>
</HEAD>
<input type=text name=count value=6000>
<INPUT type=button onclick=SubmitEnter(document.all.count.value) value="submit">
</BODY>
都是不能改变值的。
所以,任何string的运算,都会返回新的内存分配的新string
例如:
var a="okok";
那么就分配了"okok"的一个空间 [r1]
当a=a+"apple"时,
那么并不是[r1]的后面跟着补充"apple",
而是新分配一份内存[r2],同时把"okok","apple"放到[r2]中。
然后[r1]就回释放。这样的话,每次运算,都会分配新的空间。
如果字符串很长,那么效率就会明显低了。
(主要是str=str+newstr这一步)Array不同的是,Array只为新的元素分配新的内存,
原来的内容是不改动的。
而Array::join不是使用JScript的字符运算规则的。
而是内部使用常规的内存处理方法。先分配一段足够大的空间。
然后把所有内容都补上去。
整个过程,都没有内存的再分配操作。效率当然高了。。
var calltime=0;
var o=
{
toString:(function(){
calltime++;
return "("+calltime+")["+Math.random()+"]";
})
}
var a=new Array();
for(var i=0;i<10;i++)a[a.length]=o;
alert(a.join("\n"));从显示的结果,可以猜到。Array::join的过程为:
1。分配另外一个数组arr1,数组元素的个数等于Array::length
2。把Array的所有元素的toString的最终字符串返回值都压到arr1中。
3。把所有的arr1的元素的长度都加起来得到tLength,然后分配长度为tLength*sizfof(WCHAR)的内存r1
4。把arr1的所有内容都用memcpy复制到r1的相应位置。
返回封装好的[r1]的string对象
<script>var calltime=0;
var o=
{
toString:(function(){
calltime++;
return "("+calltime+")["+Math.random()+"]";
})
}
var a=new Array();
for(var i=0;i<10;i++)a[a.length]=o;
alert(a);
alert(a.join("\n"));</script>
function ArrayADD3(n,str){
return new Array(parseInt(n)+1).join(str)
}
<BODY>
var a=new Array(t+1)
alert(a.join("1"))<SCRIPT LANGUAGE="JScript">
function ArrayADD3(n,str){
return new Array(parseInt(n)+1).join(str)
}function SubmitEnter(num){
var loStartDate = new Date();
var lsHTML = ArrayADD3(num,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
var loEndDate = new Date();
alert(loEndDate-loStartDate+":"+lsHTML.length);
}
</SCRIPT>
</HEAD>
<input type=text name=count value=10000>
<INPUT type=button onclick=SubmitEnter(document.all.count.value) value="submit">
</BODY>
<SCRIPT LANGUAGE="JScript">
function StringADD3(n){
var tmp,t;
for (t=Math.round(Math.sqrt(n)); t>0; t--)if(n%t==0)break;
tmp=ArrayADD3(t,"ABCDEFGHIJKLMNOPQRSTUVWXYZ")
return ArrayADD3(n/t,tmp)
}
function ArrayADD3(n,str){
return new Array(parseInt(n)+1).join(str)
}
function SubmitEnter(num){
var loStartDate = new Date();
var lsHTML = StringADD3(num);
var loEndDate = new Date();
alert(loEndDate-loStartDate+":"+lsHTML.length/26);
}
</SCRIPT>
</HEAD>
<input type=text name=count value=10000>
<INPUT type=button onclick=SubmitEnter(document.all.count.value) value="submit">
</BODY>
<BODY>
<SCRIPT LANGUAGE="JScript">
function Repeat(str,n){
/************(qiushuiwuhen 2002-5-26)**************/
for (t=Math.round(Math.sqrt(n)); t>0; t--)if(n%t==0)break;
var tmp=new Array(t+1).join(str)
return new Array(n/t+1).join(tmp)
}
function SubmitEnter(num){
var loStartDate = new Date();
var lsHTML = Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ",parseInt(num));
var loEndDate = new Date();
alert(loEndDate-loStartDate+":"+lsHTML.length);
}
</SCRIPT>
</HEAD>
<input type=text name=count value=10000>
<INPUT type=button onclick=SubmitEnter(document.all.count.value) value="submit">
</BODY>
<BODY>
<SPAN ID="inHTML"> </SPAN>
<SCRIPT language=javascript>
function inString(){
inHTML.innerHTML += "<SPAN>ABCD</SPAN>";
}function CreaElement(){
var loSpan = document.createElement("SPAN");
loSpan.innerHTML = "ABCD";
inHTML.appendChild(loSpan);
}function test(){
inHTML.innerHTML = "";
var loStartDate = new Date();
var loHTML = new Array;
for (var i=0; i<1000; i++){
loHTML[loHTML.length] = "<SPAN>ABCD</SPAN>";
}
inHTML.innerHTML = loHTML.join('');
var loEndDate = new Date();
alert(loEndDate-loStartDate);
inHTML.innerHTML = "";
var loStartDate = new Date();
for (var i=0; i<1000; i++){
CreaElement();
}
var loEndDate = new Date();
alert(loEndDate-loStartDate); inHTML.innerHTML = "";
var loStartDate = new Date();
for (var i=0; i<1000; i++){
inString();
}
var loEndDate = new Date();
alert(loEndDate-loStartDate);
}
</SCRIPT>
<input type="button" value="submit" onClick="test()">
</BODY>
</HTML>还有例如创建 <Select> <TABLE> 等等, 如何能让它的效率更高,这样做的优缺点等等,应该应用在什么场合,希望看到高手的评论和思路...
程序好和坏就在于执行效率,编写效率只是非编程人要求的
我只有学习了。
我当然知道程序好和坏就在于执行效率,如果我们用的是汇编语言,就要对CPU,内存很熟悉.我想,使用JavaScript 没有必要去做上面讨论的那些事情吧!
而且经常动不动就是占用cpu100%这样就可能会导致用户立即关闭,
也许显示效果还没出来,也许以后就不来了你说JavaScript 是不是也应该讲究效率呢?
而且经常动不动就是占用cpu100%这样就可能会导致用户立即关闭,
也许显示效果还没出来,也许以后就不来了你说JavaScript 是不是也应该讲究效率呢?