代码的执行效率的讨论.

chenzengxi 2002-05-25 10:15:34
<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 = "";
for (var i=0; i<10000; i++){
lsHTML += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
}
return lsHTML;
}

function SubmitEnter(){
var loStartDate = new Date();
var lsHTML = ArrayJoin();
var loEndDate = new Date();
alert(loEndDate-loStartDate);

var loStartDate = new Date();
var lsHTML = StringADD();
var loEndDate = new Date();
alert(loEndDate-loStartDate);
}
</SCRIPT>
</HEAD>

<INPUT type=button onclick=SubmitEnter() value="submit">
</BODY>

上面是一个关于字符窜累加的对比,希望大家讨论一下其它有关程序写法和执行效率的问题.
...全文
39 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lostinet 2002-05-27
  • 打赏
  • 举报
回复
。。。
效率问题要看情况了。
虽然硬件发展快。
但是软件的效率目的不是程序的好坏,而是软件商的竞争啊。
Lostinet 2002-05-27
  • 打赏
  • 举报
回复
。。。
效率问题要看情况了。
虽然硬件发展快。
但是软件的效率目的程序的好坏,而是软件商的竞争啊。
weblive 2002-05-27
  • 打赏
  • 举报
回复
同意lostinet(爱情 =∫[缘分∪友谊+浪漫]d永远) 观点!!!!!!!
Andrawu 2002-05-27
  • 打赏
  • 举报
回复
qiushuiwuhen(秋水无恨),好象是一个在说话哟,呵呵。
我只有学习了。
qiushuiwuhen 2002-05-27
  • 打赏
  • 举报
回复
to linhaibo(美洲豹):(差点晕倒,嘿嘿)
程序好和坏就在于执行效率,编写效率只是非编程人要求的
linhaibo 2002-05-27
  • 打赏
  • 举报
回复
事实上,这样的程序不存在意义,
现在或者以后电脑速度越来越快,我们考虑的更多不是执行的效率,而是编写的效率.
qiushuiwuhen 2002-05-27
  • 打赏
  • 举报
回复
JavaScript 也是需要的

很多效果都是在客户端执行的
而且经常动不动就是占用cpu100%

这样就可能会导致用户立即关闭,
也许显示效果还没出来,也许以后就不来了

你说JavaScript 是不是也应该讲究效率呢?
qiushuiwuhen 2002-05-27
  • 打赏
  • 举报
回复
JavaScript 也是需要的

很多效果都是在客户端执行的
而且经常动不动就是占用cpu100%

这样就可能会导致用户立即关闭,
也许显示效果还没出来,也许以后就不来了

你说JavaScript 是不是也应该讲究效率呢?
linhaibo 2002-05-27
  • 打赏
  • 举报
回复
To: qiushuiwuhen(秋水无恨)

现在的编程语言越来越先进,程序语言开发者已经替我们解决了很多的细节问题
我当然知道程序好和坏就在于执行效率,如果我们用的是汇编语言,就要对CPU,内存很熟悉.

我想,使用JavaScript 没有必要去做上面讨论的那些事情吧!
chenzengxi 2002-05-27
  • 打赏
  • 举报
回复
呵呵,好的程序必须要考虑效率问题,这个是肯定的,应该最大限度的减少硬件的消耗。
这应该是一种习惯。
Lostinet 2002-05-26
  • 打赏
  • 举报
回复
这是一个分析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对象

Lostinet 2002-05-26
  • 打赏
  • 举报
回复
JScript的string和C#的是一样的。
都是不能改变值的。
所以,任何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的字符运算规则的。
而是内部使用常规的内存处理方法。先分配一段足够大的空间。
然后把所有内容都补上去。
整个过程,都没有内存的再分配操作。效率当然高了。。
qiushuiwuhen 2002-05-26
  • 打赏
  • 举报
回复
<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>

mmkk 2002-05-26
  • 打赏
  • 举报
回复
只是要循环多少次和tmp一次要加多少个数字以便以后替换的时候达到最佳效率怎么知道呢?
mmkk 2002-05-26
  • 打赏
  • 举报
回复
我运行StringAdd()差点就挂了,StringAdd3()的效率确实很高
qiushuiwuhen 2002-05-26
  • 打赏
  • 举报
回复
单单上面这个例子,可以做成以下效率更高点,主要思路:尽量使用小单元,小循环

<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>
saucer 2002-05-26
  • 打赏
  • 举报
回复
在这种情形下,应该ArrayJoin是快,原因如下:
在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倍!)

以上讨论中的数字只是近似,但量级应该是对的,别斤斤计较
mmkk 2002-05-26
  • 打赏
  • 举报
回复
关注,欠缺这方面的knowledge
chenzengxi 2002-05-26
  • 打赏
  • 举报
回复
呵呵,大开眼界了,别光是讨论字符窜,还有其它的,比如:

<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> 等等, 如何能让它的效率更高,这样做的优缺点等等,应该应用在什么场合,希望看到高手的评论和思路...
qiushuiwuhen 2002-05-26
  • 打赏
  • 举报
回复
更短,更快(累了,休息休息,呵呵)
<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>

加载更多回复(5)

87,910

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧