IT戦記

ただただがむしゃらにソフト開発をしていたい

複雑で重くなった 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