次のリストは、PL/I 言語の一般的なパフォーマンスに関するヒントおよび推奨事項を示しています。
- LABEL 変数の使用は避けてください。
- ON ユニットから制御を転送する場合を除き、GOTO 文は使用しないでください。代わりに LEAVE または RETURN を使用してください。
ラベル変数の使用または受け渡しによるか、有効範囲内であるがブロック外にあるラベルの参照によるかにかかわらず、現在のブロック外に存在するターゲットへの GOTO (移動) を行うすべてのコードでは、そのローカルでない GOTO の実行時にスタックを効果的にアンワインドできるように、ラベルを含むプロシージャに対して追加のプロローグ
コードを生成する必要があります。このシナリオを避けるようにコーディングすると、より速くより効率的なコードになります。
- 終わらないループには DO LOOP (または DO FOREVER) を使用し、終了条件を満たした場合に DO LOOP を終了するには LEAVE を使用してください。
- フラグでは、他の型のフィールドではなく BIT(1) を使用し、構造体を使用して同じバイトに関連フラグを統合してください。and/or (&/|) を使用してフラグの組み合わせをテストすることで、指示を減らし、より速くすることが可能です。
- 非 BIT 変数をテストする場合、IF index ^= 0 と IF index 以外など、両方の作用対象を含めることを推奨します。
- 暗黙的な比較は避けてください。たとえば、すべての作用対象が BIT(1) であると想定する場合、b1 = b2 = b3; ではなく b1 = ''b; IF b2 = b3 then b1 = '1'b; とすることを推奨します。 IF b2 = b3 then b1 = '1'b; else b1 = '0'b;
- 可能であれば、確率が低い比較の前に、(true または false になる) 確率の最も高い比較を指定して、確率順に文/式を並べることを推奨します。
- REPEAT、UNTIL、および WHILE 構文を使用して、プログラム ロジックを表現してください。コンパイラは、それらを最も効率的な方法で処理します。
- SELECT...WHEN...OTHERWISE 文グループは、プログラムの可読性および保守容易性を向上させ、入れ子になっている IF 文よりも効率的なコードを生成できます。SELECT グループを使用する場合は、OTHERWISE 文をコーディングすることを推奨します。コーディングしない場合、実際上、コンパイラによって
OTHERWISE SIGNAL ERROR; 文が挿入されます。
- 多くの小さいプロシージャを作成して、過剰にモジュール化を使用しないようにしてください。
- BEGIN 文は、ON-unit の本文になっているか、通常とは異なる量の自動記憶域 (および、場合によっては動的に必要な/要求ベースで必要な記憶域のみ) を動的に割り当てる必要がある場合を除き、使用を避けてください。
- 複合文を使用すると、コンパイラがターゲットを「認識」できるようになり、大きい一時記憶域を必要とする場合がある連結 (||) などの操作では特に、より優れたコード生成が可能になります。次に例を示します。
-
Target += expression; は、次のように記述するよりも優れています。 Target = Target + expression;
- Target ||= expression; は、Target = Target || expression; よりも優れていますが、機能するのは Target is VARYING の場合のみです。
- 1 つの END 文で複数のグループ (DO、SELECT) またはブロック (BEGIN、PROCEDURE) を終了する場合、コンパイラを使用しないでください。誤りが発生する可能性が非常に高く、パフォーマンスに影響する可能性があります。
- プロシージャ内に複数のエントリ ポイント (ENTRY 文) がある場合、パラメーターを再マッピングする追加指示またはパラメーターの使用を判定するテスト (あるいはその両方) が発生する可能性があります。プロシージャが関数である場合、すべてのエントリ
ポイントを関数にし、それらが同じデータ型を返すようにすることを推奨します。戻り型が異なると、場合によって複雑となるコンパイラ生成の SELECT グループの制御下で変換コードが生成される可能性があります。
- FETCH 文を使用する場合は、次のように記述することが推奨されます。
DCL fe entry[( …)] options(fetchable […]);
DCL fev entry variable;
fetch fe;
fev = fe;
Call fev [ (….) ]; /* note fev entry variable is being called here */
上記のコードの方が次のコードよりも効率的です。
DCL fe entry[( …)] options(fetchable […]);
Call fe [ (….) ]; /* note fe entry constant is being called here */
必要なくなったフェッチ済みエントリの RELEASE (解放) を適宜行うことを推奨します。
- 動的に割り当てられた記憶域を使用する場合、アプリケーション ロジック上可能であれば、必要に応じて記憶域の ALLOCATE (割り当て) を行い、終了時にその FREE (解放) を行う方が効率的になる可能性があります。また、アプリケーション
ロジック上可能であれば、記憶域の寿命が尽きるまで BEGIN ブロックを使用することで効率が大幅に向上します。AUTOMATIC 記憶域は、数個の指示で割り当てでき、解放に必要な指示はさらに少なくなります。次に例を示します。
DCL some_storage char(some_len) based(stg_ptr),
Some_len = expression;
ALLOCATE some_storage;
[ … storage use .. ]
FREE some-storage;
上記のコードは、次のさらに効率的なコードに置き換えることができます。
BEGIN;
DCL some_storage char(some_len) [AUTO];
[ … storage use .. ]
END;