第四章-アルゴリズムとフロー制御

2436 ワード

コードの数は運行速度と密接に関係していません.コードの運行速度に影響する主な要因は、コードの組織構造と問題解決の具体的な考え方である.
ループ
ほとんどのプログラミング言語では、コード実行時間はほとんどサイクル中に消費されます.サイクルは最も一般的なプログラミングモードの一つであり、性能を向上させる上で注目すべきポイントの一つでもある.
ループのタイプ
JavaScriptには4つの循環タイプがあります.
  • 標準のforサイクル:
  • for (var i=0; i < 5; i++) {
        // do sth
    }
    
    forサイクルはJavaScriptで最も一般的な循環構造である.これは四つの部分から構成されています.初期化、前測定条件、後実行体、循環体.コードがforサイクルに遭遇したら、初期化コードを実行して、事前測定条件に入ります.前測定条件がtrueであれば、循環体を実行します.循環体を実行した後、コードを実行して運転を開始します.
  • whileサイクル
  • var i = 0;
    while(i < 10) {
        // do sth
        i++;
    }
    
    whileサイクルは一つの前測定条件と一つの循環体から構成される.循環体が運転する前に、事前測定条件を計算します.計算結果がtrueであれば、循環体を実行します.どのforサイクルもwhileサイクルに書き換えられます.
  • do-whileサイクルdo-whileサイクルはJavaScriptの中で唯一の事後測定サイクルである.それは循環体と後測定条件から構成されています.
  • var i = 0;
    do {
        //    
    } while (i++ < 10)
    
    do-whileサイクルの中で、循環体験は少なくとも一回実行します.その後、再実行するかどうかを測定条件で決定します.
  • for-i-nサイクルは、任意のオブジェクトのオブジェクト名を列挙することができます.
  • for (var prop in object) {
        // do sth
    }
    
    循環体が各動作するたびに、prop変数はobjectの属性名に割り当てられ、すべての属性が巡回してから戻ってきます.プロトタイプチェーンからオブジェクトを継承する属性が含まれます.
    サイクル性能
    上記の4つの循環タイプの中で、for-i-nサイクルだけが明らかに遅いです.
    反復毎の動作は、インスタンスまたはプロトタイプの属性を同時に検索するので、for-iループの反復ごとに、より多くのオーバーヘッドを生成する.同じ回数のサイクルを比べると、for-i-nサイクルは最終的に他のタイプの速度の1/7しかないです.したがって、属性の数が未知のオブジェクトを反復する必要が明確でない限り、for-innの使用は避けるべきである.
    サイクルタイプが性能に関係がないなら、次の2点から最適化できます.
  • 毎回繰り返し処理するもの
  • 反復の回数
  • 反復の作業量を減らす
    循環全体の速度を向上させる良い方法は、循環時間当たりの動作数を制限することである.
    //         
    for (var i=0; i < items.length; i++) {
        //       
        process(items[i])
    }
    
    上記の例では、ループを実行するたびに必要な作業は以下の通りである.
  • 制御条件で属性を検索する
  • .
  • 制御条件における一回の比較(i<items.length)
  • 制御条件の結果がtrue
  • かどうかを確認する.
  • 自己増加操作(i++)
  • 配列検索(items[i])
  • 次関数呼び出し
  • コードの実行速度は、関数によって大きく異なります.プロcessを呼び出します.の消費時間を短縮します.しかし、反復の回数が少ない分、サイクル性能を大幅に向上させます.最適化サイクルの第一歩は、オブジェクトのメンバーと配列項目の検索回数を減らすことです.前の例では、各ループごとにitems.lengthを検索します.このような操作は時間がかかります.この値によって動作中は変化せず、ローカル変数に保存できます.制御された条件でこの変数を使います.
    //        
    for (var i=0, len=items.length; i < len; i++) {
        process(items[i])
    }
    
    上の最適化により、配列の長さに応じて、ほとんどのブラウザで25%の時間を節約できます.また、順序を逆転して循環することで、循環性能を向上させることもできます.
    //          
    for (var i=items.length; i--; ) {
        process(items[i])
    }
    
    上記の例は倒順サイクルを使用し、減法を制御条件に置いています.現在は各制御条件を単純に0と比較するだけです.制御条件は2回の比較(代数が合計より少ないですか?trueですか?)から1回の比較に減少します.
    上の二つの最適化を経て、実行速度は元のバージョンより約50%-60%速いです.
    未完