SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 採用情報 ...
技術者募集中

【Javascript】複数の関数を連続して実行する方法を試してみる

へんてこな?ことを試してます。意味不明だったらすみません。

概要

ある文字列が、ある複数の条件を満たしているかどうか判定したい。

1つ1つの条件判定は1つ1つ関数にするのだが、以下の2つの呼び出し方のどちらが速いか。

手順1 – 素直に1つずつ実行

ごく普通の風景。

function fn1(x){return "判定結果";}
function fn2(x){return "判定結果";}
function fn3(x){return "判定結果";}
function fn4(x){return "判定結果";}
function fn5(x){return "判定結果";}
if (fn1(x) && fn2 (x) && fn3(x) && fn4(x) && fn5(x)) {
    //全部trueだったらOK
} else {
    //ひとつでも途中でfalseだったらNG
}

手順2 – 数珠つながりにしてfn1だけ呼べばよいようにする

関数の配列を作るなどするとおもしろい数珠つながりが作れる(後でやってみる)

function fn1(x){return "判定結果" && fn2(x);}
function fn2(x){return "判定結果" && fn3(x);}
function fn3(x){return "判定結果" && fn4(x);}
function fn4(x){return "判定結果" && fn5(x);}
function fn5(x){return "判定結果";}
if (fn1(x)) {
    //trueだったら全部OKということ
} else {
    //falseだったら途中でNGがあったということ
}

実際にやりたいことに近いことをやってみる

なぜこんなことをしているかというと、ユーザーの入力に応じて判定条件を変えたいので、臨機応変に判定関数を組み合わせて実行したいから。

以下のサンプルコードの「/1/.test(x)」は、文字列xが文字”1″を含んでいればtrue、含んでいなければfalseが返ってくる(参考:RegExp.test)。

手順1のテスト

//判定関数を用意する(配列に入れておく。順次実行するときはfor文を使うことになる。)
var fn = [];
fn.push(function(x){return /1/.test(x);});
fn.push(function(x){return /2/.test(x);});
fn.push(function(x){return /3/.test(x);});
fn.push(function(x){return /4/.test(x);});
fn.push(function(x){return /5/.test(x);});

//100000回試すテスト
var start = new Date().getTime();
for (var n = 0; n < 100000; ++n) {
    var hantei = true;
    var x = "123456789";
    for (var i = 0, l = fn.length; i < l; ++i) {
        if (!fn[i](x)) {
            //falseが返ってきたら、判定中止
            hantei = false;
            break;
        }
    }
    //hantei を見ると判定結果が分かる
}
var end = new Date().getTime();
alert(end - start);

結果 → 328ミリ秒

手順2のテスト

//判定関数を用意する(配列に入れておく。1つ目(fn[0])をキックすると数珠つながりに実行されるように仕掛けておく。)
var fn = [];
fn.push(function(x, i){return /1/.test(x) && fn[i + 1](x, i + 1);});
fn.push(function(x, i){return /2/.test(x) && fn[i + 1](x, i + 1);});
fn.push(function(x, i){return /3/.test(x) && fn[i + 1](x, i + 1);});
fn.push(function(x, i){return /4/.test(x) && fn[i + 1](x, i + 1);});
fn.push(function(x, i){return /5/.test(x);});

//100000回試すテスト
var start = new Date().getTime();
for (var n = 0; n < 100000; ++n) {
    var x = "123456789";
    var hantei = fn[0](x, 0);
    //hantei を見ると判定結果が分かる
}
var end = new Date().getTime();
alert(end - start);

結果 → 296ミリ秒

結果

数珠つながり方式が意外とまともに使えそうだった。

どこかですでに使われているだろうか。

関連するメモ

コメント