2016-09-24 6 views
1

私は、データのセットが条件の非常に小さなリストと一致するかどうかを調べたいユースケースを持っています(議論のために、20未満であるとしましょう)。ループの効率ifステートメント

私はクライアントとサーバー側(NodeJS)の両方でJavaScriptを実行しています。私は2つのオプション(またはあなたが持つかもしれない他のもの)の中から選択しようとしていますが、複雑さと計算時間がどのように違うのか分かりません。私は彼らがごくわずかだと感じています。

オプション1:オプション2はOであるJavaScriptのに条件

if (data.a === 'foo' && data.b !== 'bar' && ...) { 
    // Passes 
} 

Oでオプション1を実行する(n)を変換(:条件

var conditions = [{ 
    prop: 'a', check: '===', val: 'foo' 
}, { 
    prop: 'b', check: '!==', val: 'bar' 
}]; 

for (var i=0;i<conditions.length;i++) { 
    // Check conditions[i] 
    if (conditions[i].check === '===') { 
    if (data[conditions[i].prop] === conditions[i].val) { 
     // Keep checking 
    } else { 
     // Fail 
    } 
    } else if (conditions[i].check === '!==') { 
    ... 
    } 
} 

オプション2の反復リスト1)、技術的には、しかし、実際にこのような小さなリストでは、特にあなたがJSON.eval()を行うのにかかる時間を考慮し、アカウントのユニークなコードを提供することが重要ですか?

+3

Profile it。他のすべてはブードゥー最適化です。 – BradHards

+1

おそらく、オブジェクトのプロパティに基づいて式言語を作成しようとしないでください。代わりにジェネリック関数を使用して、JavaScriptで定義済みの演算子を処理してください。 –

+0

私は十分なユースケースを与えていないようです。 'conditions'はユーザが提供する条件のリストなので、未知入力に基づいてデータを評価する方法が必要です。私は、Javascriptのコンパイル、リストの反復、さらにはデータベースサーバ上でのユーザ定義関数の実行を実験しています。何千ものクライアント(カスタムの 'condition'配列)に対して効率的かつスケーラブルなソリューションを見つけようとしています。 – knation

答えて

2

まず、evalは(ほとんどの場合)です。

これらのすべての条件でコードが醜いように見えますが、条件が満たされていないとパフォーマンスが低下するというパフォーマンス上の問題があります。結局、解析するのに少し時間がかかりますが、実行するのには時間がかかります。

反復回数が少ない場合、最初の例を使用したときのパフォーマンスは問題にはなりません。

時間の使用状況を正確に測定したい場合は、テストを書くだけです。

1

一般に、条件リストを「コンパイル」することは、実際に問題がある場合は、それらを「解釈する」よりもかなり高速になります。あなたがベンチマークするかどうかを判断する必要があります。 evalを使用するか、Functionコンストラクタを使用して「コンパイル」できます。しかし、このようなアプローチは、本当に必要な場合にのみ行われるべきであり、まれなケースであるはずです。

しかし、あなたがなぜこの小さな言語を使ってチェックしているのかわかりません。 "言語"によって、私は形のものを意味する{prop: 'a', check: '===', val: 'foo'}。あなたはそれらのことを書く必要があります。実行時にそれらを解析する必要があります。実行時にそれらを実行する必要があります。 JavaScriptには、このような機能をカプセル化するための完全な方法が既に用意されています。それらを「関数」と呼びます。他の利点の中でも、そのような機能は、十分な時間が呼び出されれば、エンジンによって最適化され得る。あなたの問題へ

機能ベースのアプローチは、書くことのようになります。

var conditions = [ 
    data => data.a === 'foo', 
    data => data.b !== 'bar' 
]; 

for (var i=0;i<conditions.length;i++) { 
    // Check conditions[i] 
    if (conditions[i](data)) { 
     // Keep checking 
    } else { 
     // Fail 
    } 
    ... 
    } 
} 

以上の口語的

conditions.every(condition => condition(data)) 

どんなにあなたがこれを書くか、パフォーマンスは基本的に数がO(n)ではありません条件。行われている比較/テストの回数は変わりません。問題は、大きなO命令ではなく、それらのテストを実行する速度です。

+0

'conditions'はユーザが定義した条件の集合なので、記述したようにコンパイルできません。 – knation

+0

質問はあなたが相対的または絶対的な用語で「無視できる」を意味するかどうかです。相対的に言えば、大きな違いがあります。絶対的にはそうではないでしょう。 –

関連する問題