素人がプログラミングを勉強していたブログ

プログラミング、セキュリティ、英語、Webなどのブログ since 2008

連絡先: すかいぷ:javascripter_  か javascripter あっと tsukkun.net skypeのほうがいいです

forループを多少高速化する方法

インクリメントするんじゃなくてデクリメントすれば、lengthプロパティへのアクセスを減らせて高速化ができる。
たとえば、

var foo=new Array(1000000);

var start=new Date().getTime();
for(var i=0;i<foo.length;i++);
var end=new Date().getTime();
end-start;

は僕のPCでは940msだったけど、

var foo=new Array(1000000);

var start=new Date().getTime();
for(var i=foo.length-1;i>=0;i--);
var end=new Date().getTime();
end-start;

だと、720ms。220msも早くなった!

ループが逆向きになるからpushの代わりにunshift使えばいい。


追記:なんか早くならないこともある。

僕の環境だと

var $X=function(xpath,context){
var x=document.evaluate(xpath,context||document,null,7,null),r=[];
for(var i=x.snapshotLength-1;i>=0;i--)r.unshift(x.snapshotItem(i));
return r;
}
var start=new Date().getTime();
$X('//*');
new Date().getTime()-start;

に7msかかったけど、

var $X=function(xpath,context){
var x=document.evaluate(xpath,context||document,null,7,null),r=[];
for(var i=0;i<x.snapshotLength;i++)r.push(x.snapshotItem(i))
return r;
}
var start=new Date().getTime();
$X('//*');
new Date().getTime()-start;

だと4ms。

最適化されてんのかな?
これはきっと、document.evaluateのsnapshotLengthはただのハッシュだから、変数にアクセスするのと負荷が変わらないんだと思う。ということで、この方法は生きたノードリストの場合に効果があると思う。