作者sk1765 (鼎玉鉉)
看板Ajax
標題Re: [問題] 程式執行效率的問題
時間Mon Jan 24 02:10:12 2011
var input = [],output=[];
var input1=[],output1=[];
function times(n, f) {
var c=0;
return function() {
var args = [];
for(var i=0,j=arguments.length; i<j; i++) {
alert("[i=" + i + "][c=" +c+ "]: " +arguments[i]); //<-增加了這行觀測
args.push(arguments[i]);
}
if(c<n) {
c++;
return f.apply(this, args);
} else {
return null;
}
};
}
var work = function(res) {
return res.shift();
};
var f1 = times(10, work);
var r1 = function(res, f) {
var ret = f(res);
if(null !== ret) {
output.push(ret);
r1(res, f);
}
};
var r2 = function(n) {
for(var i=0; i<n; i++) {
output1.push(work(input1));
}
};
function test1() {
input = [0,1,2,3,4,5,6,7,8,9];
output = [];
r1(input, f1);
}
function test2() {
input1 = [0,1,2,3,4,5,6,7,8,9];
output1 = [];
r2(10);
}
var count = 100000;
var d1 = new Date().getTime();
for(var i=0; i<count; i++) {
test1();
}
var d2 = (new Date().getTime()) - d1;
var d3 = new Date().getTime();
for(var i=0; i<count; i++) {
test2();
}
var d4 = (new Date().getTime()) - d3;
alert(d2);
alert(d4);
----------------------------------------------
以上程式我只增加了一行觀測用
alert("[i=" + i + "][c=" +c+ "]: " +arguments[i]);
發現問題出在 var c變數
由於times 傳回一個匿名函式 該匿名函式為一closure
c這個變數 由於closure的關係 將一直維持private的存在
所以當執行一萬次test1時
for(var i=0; i<count; i++) {
test1();
}
只有第一次 c會由0-9 正常運作
後面的9999次test1 的執行 c都維持在10
也就是times fumction 一進去就跳出來 因為c>n 等於沒執行
所以並不是test1的執行效率比test2高
而是test1只真正執行了一次 而test2執行了一萬次
程式執行中 若覺得alert 10000次按的很辛苦 請用程式管理員直接結束ie or ff
---------------------------------------------
解決這個問題的方法如下
function test1() {
input = [0,1,2,3,4,5,6,7,8,9];
output = [];
r1(input, times(10, work));
}
test1 裏面 r1(input,f1) 改成r1(input, times(10, work))
這兩者是有差異的
times(10, work) 每次都會執行一遍 所以回傳的匿名函式 c值重新歸零
f1是一個指向傳回來的匿名函式的指標 那個匿名函式一直沒變
所以總結來說 應該是times的用法用錯了
不能用f1= times(10, work);這樣的寫法
times函式每次使用時都必須呼叫一遍取得新的匿名函式 而不能只呼叫一遍
如果一定要用f1= times(10, work);這句則必須擺在r1之前如下:
function test1() {
input = [0,1,2,3,4,5,6,7,8,9];
output = [];
f1= times(10, work);
r1(input, f1);
}
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 203.70.99.74
※ 編輯: sk1765 來自: 203.70.99.74 (01/24 02:26)
※ 編輯: sk1765 來自: 203.73.175.240 (01/24 12:14)
※ 編輯: sk1765 來自: 203.73.175.240 (01/24 12:18)
1F:推 fillano:感謝阿 01/31 10:08