建築ヤス。 パート3:選択の問題

これはYASSの基礎となる実用的な方法の分析に専念するシリーズの3番目の記事です。 最初の記事はモジュール構造についてであり、2番目はCSSセレクターを選択してループを組織する論理についてでした。

条件分岐



分岐のロジックの最も明白なコンポーネントから始めましょう。 どのアルゴリズムでも、チェックされる条件に応じて、1つまたは別の継続を選択する必要がある場所があります。 次の例を見てみましょう。 最初のケースでは、3つの単純なネストされたチェックがあります。

  var a = 1
	 b = 2
	 c = 3;
 if(a == 1){
	 if(b == 2){
		 if(c == 3){
			 ...
		 }
	 }
 } 


最も興味深いのは、次のif組み合わせたifと同じくらい高速if

  if(a == 1 && b == 2 && c == 3){
	 ...
 } 


ただし、後者はわずかに小さくなります。 目標が最小コードサイズではない場合、読みやすさを向上させるには、最初のオプションを使用する必要があります。 すべてを最小化するif-then-elseif-then-else式の使用を検討できif-then-else 。 ただし、このような構造のパフォーマンスは次の点に留意する必要があります。

  var v = a == 1?  b == 2?  c == 3?  1:0:0:0; 


通常の分岐よりも約10〜50%少なく、少し高いと考えられます。

すべての変数が数値である場合、指定された合計の等値のチェックは5〜10%高速に実行されます。

  if(a + b + c == 6){
	 ...
 } 


変数の存在とその非負性(つまり、変数がundefinedではない、 NaNnull'' 、0ではない)だけをチェックする必要がある場合、次のオプションは5-10%高速に動作します。前のケースよりも(および最初の例よりも10〜20%高速):

  if(a && b && c){
	 ...
 } 


多くの場合、単なる数字よりも複雑なものをチェックする必要があります。 たとえば、指定された1つ以上のオブジェクトと文字列が一致します。 この場合、次の比較が必要です。

  var a = 1
	 b = 2
	 c = '3';
 if(a == 1 && b == 2 && c === '3'){
	 ...
 } 


ここでは、 ===をキャストせずに比較を使用します。これは、非数値変数の場合、通常の比較よりも10〜20%高速です。

行選択



多くの場合、特定の行に基づいて条件分岐の1つを選択する必要があります。 通常、これにはRegExpオブジェクトのメソッド( exectest )または文字列メソッド( matchsearchindexOf )が使用されます。 文字列が何らかの正規表現に一致するかどうかを確認する必要がある場合testtest最良のtestです。

  var str = 'abc'、
	 regexp = new RegExp( 'abc');
 if(regexp.test(str)){
	 ...
 } 


このような設計は、同様のexecよりも40%高速に動作します。

  if(regexp.exec(str)[1]){
	 ...
 } 


文字列メソッドのmatch 、作成されたRegExpオブジェクトのexecメソッドに似ていますが、単純な式では10〜15%高速に動作します。 ただし、 searchメソッドはtestよりも少し遅く(5〜10%)動作します。これは、後者が見つかった部分文字列を返さないためです。

「1回」正規表現が必要な場合は、より高速な(新しいオブジェクトの初期化オプションに比べて約10%の)レコードが適しています。

  if(/abc/.test(str)){
	 ...
 } 


最後に、部分文字列が指定された文字列にあるかどうかを確認する必要がある場合、 indexOfは議論の余地のないリーダーになり、正規表現の解析よりも2倍速く動作します。

  if(str.indexOf( 'abc')!= -1){
	 ...
 } 


完全一致とハッシュ



次の正規表現を考えてみましょう: /a|b|c/ 。 この場合、指定された行で可能なオプションの1つ(またはこのオプションと文字列の等価性)の存在を確認する必要があります。 完全一致の場合、正規表現よりも高速(50%)で、文字列がハッシュのキーとしてチェックされます。

  var hash = {'a':1、 'b':1}、
	 str = 'a';
 if(h [str]){
	 ...
 } 


このようなハッシュの高速化(20%)は、特定の値の文字列の正確なチェックのみになります。

  if(str === 'a' || str === 'b'){
	 ...
 } 


ネストされたif 、対応する値にswitchてハッシュ内の値をチェックする3つの構成要素を検討するif 、次の興味深い機能に注目する価値があります。 ネストのifレベルが少ないif (値が数個しかない場合、または最初または2番目の値を非常に頻繁に終了する場合)、 ifおよびswitch構造はハッシュでパフォーマンスが約10%向上します。 多数の値があり、それらがすべてほぼ同じ確率である場合、一般的な場合のハッシュはすでに20%速くなっています。 これは、関数の呼び出しだけでなく、変数値の確立にも同様に適用されます。 つまり、関数呼び出しでブランチを作成するには、ハッシュを使用するのが最善です。

YASSに戻る。 CSSセレクターを分析するとき、いくつかのサブタスクを区別できます。これらのサブタスクは「選択問題」として説明されています。



要約表



文字列をチェックするさまざまな方法について少し要約すると、次のようなテーブルを作成できます。

挑戦するソリューションツール
数値チェック通常の比較( ==
複数の数値の確認金額の比較
数値がゼロでないことを確認するか、存在を確認します与えられた変数の否定をチェックする( !
文字列を解析し、パーツを配列に割り当てるString.match(RegExp)またはRegExp.exec(String)
正規表現の文字列を確認してくださいRegExp.test(String)
サブストリングのストリングを確認してくださいString.indexOf(String)
文字列の正確な対応(または値セットの1つと一致)の確認キャストなしのif===
正確な値に基づく選択(値1〜2)条件付きif構文
正確な値に基づく選択(値3〜8)switch
正確な値(8より大きい値)に基づく選択値に一致するキーを持つハッシュ


おそらく、この表にさらにいくつかのケースを追加するか、JavaScriptでの単純な構造パフォーマンスに関する記事を参照して、適切な結論を引き出すことができます。

継続するには...

Source: https://habr.com/ru/post/J50210/


All Articles