IT戦記 このページをアンテナに追加 RSSフィード Twitter

2006-01-14

複雑で重くなった JavaScript を超超ちょ〜〜〜高速化する方法。

前回(id:amachang:20060104)の改良版です。前回のでやっていたら、queueを走査する時間がかかりすぎるようになって結局崩壊してしまったので、さらに改良しました。ただし、今回のは時間が多少ずれる場合があります。なので、ストップウォッチなどのプログラムを作る場合は使わないでください。

主な改良点としては

  1. .(ドット) 減らす。
  2. 文字列リテラルをループ中に記述しない。
  3. ループ。ループのネストを減らす。
  4. new を減らす。
  5. 関数コールを減らす。
  6. より早い演算を使う。(+1 を ++ にするとか。他にもいっぱい)

これで、めっちゃ早くなりました。やヴぁいです。

ミニマム版
var _SIi=10,_SIM='第一引数が不正です。',_SIl=0,_SIc=0,_SIS ='string',_SIF='function',_SIf=window.setInterval,_SIp=[],_SIn=[];window.setInterval=function(p, d){if(typeof p==_SIS)p=new Function(p);else if(typeof p!=_SIF)throw Error(_SIM);var i;for(i=0;;i++)if(!_SIp[i]) break;_SIn[i]= Math.floor(d/_SIi) || 1;_SIp[i]= p;if(_SIl==i)_SIl++;return ++i;};window.clearInterval=function(i){i--;_SIp[i]=undefined;if(!((--_SIl)==i))_SIl++;};_SIf(function(){_SIc ++;for(var i=0;i<_SIl;i++){var p=_SIp[i];if(!(_SIc%_SIn[i])&&p)p();}},_SIi);
ヒューマンリーダブル版
var _si_Interval            = 10;
var _si_ProcessCounter      = 0;
var _si_Counter             = 0;
var _SI_MESSAGE_ERROR       = '第一引数が不正です。';
var _SI_TYPE_STRING         = 'string';
var _SI_TYPE_FUNCTION       = 'function';
var _si_NativeSetInterval   = window.setInterval;
var _si_ProcessArray        = [];
var _si_TimingArray         = [];

window.setInterval = function(process, delay) {
    if(typeof process == _SI_TYPE_STRING) {
        process = new Function(process);
    }
    else if(typeof process != _SI_TYPE_FUNCTION) {
        throw Error(_SI_MESSAGE_ERROR);
    }
    var id;
    for(id = 0; ; id ++) {
        if(!_si_ProcessArray[id]) {
            break;
        }
    }
    _si_TimingArray[id]  = Math.floor(delay / _si_Interval) || 1;
    _si_ProcessArray[id] = process;
    if(_si_ProcessCounter == id) {
        _si_ProcessCounter ++;
    }
    return ++id;
};

window.clearInterval = function(id) {
    id--; _si_ProcessArray[id] = undefined;
    if(!((-- _si_ProcessCounter) == id)) {
        _si_ProcessCounter ++;
    }
};

_si_NativeSetInterval(
    function() {
        _si_Counter ++;
        for(var i = 0; i < _si_ProcessCounter; i ++){
            var process = _si_ProcessArray[i];
            if(!(_si_Counter % _si_TimingArray[i]) && process) {
                process();
            }
        }
    },
    _si_Interval
);

ライセンスはこの日記にコメントすること(寂しがり屋ライセンス)

そのうち、サンプル公開しますよ〜

もっと早く出来るよ〜って人は教えてください。実測して、報告し、修正します。

最新はこっちです

id:amachang:20060924:1159084608

SeacolorSeacolor 2006/01/15 13:06 寂しがり屋ライセンス、良いですね(笑)
ありがたく使わせていただきます。

shinshin 2006/01/21 01:50 ソース読んでいて、とても参考になりますー。
私も使わせていただきます。

arakanearakane 2006/01/26 16:04 寂しがらないでください(^^;
僕も使わせていただきますm(__)m

anstainanstain 2006/01/27 00:34 おおお、良いですね、これ。(^^
使わせてもらいます。

noricyannoricyan 2006/02/09 15:44 使わせていただきます

nonenone 2006/02/14 04:41 使わせて頂きます。
本家に早くなるパッチとして部分的にでも送って頂けると皆さんが幸せになれる気がしますがいかがでしょうか?是非ご検討下さい

KurageKurage 2006/02/16 13:16 はじめまして、少し改変してみました。
http://qurage.net/labo/xInterval.txt
実測はしていないので何とも言えないのですが(つω`;

karanekokaraneko 2006/02/22 22:31 使わせていただきます!

amachangamachang 2006/02/26 13:55 最近、仕事仕事で忙しくて返信できなくてすみません。いくつか、改変案があったので時間が空き次第ベンチマークを取ってみますです。みなさん、ホントにありがとうございます。

tttt 2006/02/28 20:29 こういうやり方もあるのですね、使わせてもらいます

namidnamid 2006/03/27 22:27 ただ貼り付けるだけで本当に軽くなりました・・・。
どうしてそうなったのか、ぜひぜひ解説おねがいします!!!

めちゃめちゃ感動しました。

eggegg 2006/04/04 23:05 使わせていただきますよ〜
そしてソースがめっちゃ参考になります。いいワァ

konakona 2006/04/25 19:33 すごいですね!!
javascriptはどうしても重くなってしまいがちなので
ほんと助かります。
これからもがんばってください〜!

noanoa 2006/05/09 16:48 いつも拝見させていただいてます。
めちゃめちゃ使いたいので使わせてください^^

soso 2006/05/29 06:54 良さそうなので使わせて頂きます&勉強させて頂きます。

tntn 2006/05/30 11:51 同じく、試しに使わさせていただきます。

strollstroll 2006/06/04 01:58 とても速くなった気がするので使わせていただきます^^

mm 2006/06/08 16:51 某商用サイト内のアプリで使わせていただきましたm(_ _)m
ただ、setIntervalが同時に実行されるケース自体が少ない(setTimeoutを必要なときに必要な回数使っている)ので、効果のほどは良く分かりません。
ところで最初のforはfor(id = 0; _si_ProcessArray[id]; id ++);で良いかも。
あとfor(var i = 0; i < _si_ProcessCounter; i ++){のところもfor(var i = 0,process; i < _si_ProcessCounter; i ++){にするとかifではprocessを先に評価するとかがあるかも。

kazkaz 2006/06/17 02:25 とても面白そうなのでぜひ使わせて下さい。

owenowen 2006/07/21 09:44 使わせていただきます!!

SumisabuSumisabu 2006/07/24 23:56 こっちが新しいんですね、使わせていただきます!

jjjj 2006/09/04 20:29 いつも勉強させていただいてます!
使わせていただきます〜!

HashHash 2006/09/14 09:54 画像をひたすら読むアプリで遅かったのですが、
かなり速くなりました。ありがとうございます。
javascript初心者なので勉強させてもらいます。

たつたつ 2006/09/20 02:13 う〜ん、私のIEでは20060104版の方が全然早いです。。。
なぜこちらは遅いんだろう。時間がある時探ってみます。

k-sukek-suke 2006/09/21 23:25 有り難く使わせて頂きますm(_ _)m ちょ〜〜〜はえーー ♪♪♪

はぴおはぴお 2006/09/22 14:16 お願いですから〜お願いですから〜
jsファイルにして配布して下さい〜

iizukaiizuka 2006/10/25 12:23 ありがたく使わせて頂きます。
すばらしいスクリプトですね。

aiai 2006/12/11 10:49 使わせていただきます〜。

yyyy 2007/04/06 21:20 ありがたく使わせて頂きます。
丁度、firefoxでのsetInterval複数起動で
あまりにも遅くて困っていました。。

wolwol 2007/06/15 12:20 速くなったぁー。使わせて頂きます。ありがとうございました。

NaruNaru 2007/07/28 20:39 自分の制作途中のライブラリに一部改変して組み込んでみました。は、速い!
ありがとうございます!

yytamakuroyytamakuro 2007/10/11 14:32 JQueryのUIサンプルとあわせて使ってみましたが、速くなっているような気がします。
ありがとうございます。

techmediatechmedia 2007/11/11 14:01 速いですね!JavaScriptゴリゴリでロード後の処理が1分ちょっとかかってましたが、45秒まで一気に縮みました。ありがたく使わせて頂きます。

myomyo 2008/01/30 13:07 大変参考になります!ありがたく使わせていただきます。
ありがとうございます!

a10a10 2008/02/10 16:02 これは使えそうですね♪
いただいていきますo

strikerstriker 2008/03/19 14:46 ありがたく使わせていただきます〜。

amachangamachang 2008/03/19 14:58 どもどもでs!

ARNIEARNIE 2008/04/22 11:16 お。。こんな方法があったとは、、、

使わせていただきます。感謝!

chrhsmtchrhsmt 2008/10/24 03:05 使わせて頂きます。

http://chrhsmt.com/about.html

shinriyoshinriyo 2012/01/12 20:15 試してみます。

はてなユーザーのみコメントできます。はてなへログインもしくは新規登録をおこなってください。