「予約語がない」というPL/Iの深淵 ― FIXED BINARYの精度とストレージ最適化の勘所
メインフレームの保守現場で若手からよく聞かれる質問がある。「なぜPL/Iには予約語がないのか? コンパイラはどうやってコードを解釈しているんだ?」と。
PL/Iの設計思想は、一言で言えば「寛容かつ強力」だ。`IF`という識別子すら変数名として使えてしまうこの言語は、文脈依存の解析によって成り立っている。これは自由であると同時に、読み手を混乱させる諸刃の剣でもある。今日は、その自由度の影で、最も「数値」の挙動にシビアな影響を与える`FIXED BINARY`型の深淵について、実務的な視点で掘り下げていこう。
—
FIXED BINARY(p, q) の「p」と「q」を使いこなす
多くのエンジニアが「なんとなく」で使いがちな`FIXED BINARY(15, 0)`や`FIXED BINARY(31, 0)`。これらは単なる数値型ではない。内部表現の境界を意識するか否かで、あなたのバッチプログラムのI/O効率は劇的に変わる。
- FIXED BIN(15, 0): 2バイト(ハーフワード)。-32,768 ~ 32,767。
- FIXED BIN(31, 0): 4バイト(フルワード)。-2,147,483,648 ~ 2,147,483,647。
ここで重要なのは、`p`の値をむやみに大きくしないことだ。例えば`FIXED BIN(16, 0)`と宣言した瞬間、コンパイラはそれを4バイトのフルワードとして確保する。2バイトで収まるはずのデータに4バイトを割り当てるのは、レコード長が数万バイトに及ぶVSAMファイルや固定長順次ファイルにおいては、無駄なストレージ消費とキャッシュ効率の低下を招くだけだ。
実践的コード例:効率的な定義と演算
以下に、実務で頻出する定義と、VSAM読み込み時の注意点をコード化した。
/i
/ —————————————————————— /
/ FIXED BINARYの効率的な定義と計算のサンプル /
/ —————————————————————— /
TEST_PROG: PROC OPTIONS(MAIN);
/ 2バイトで足りるカウンタは必ず15ビットで定義する /
DCL LOOP_CNT FIXED BIN(15, 0) INIT(0);
/ 金額計算など、フルワード境界が必要な場合は31ビットを明示 /
DCL TOTAL_AMT FIXED BIN(31, 0) INIT(0);
/ VSAM等からのマッピング用レコード /
DCL 1 INPUT_REC,
5 KEY_ID CHAR(8),
5 QTY FIXED BIN(15, 0), / ストレージ節約 /
5 PRICE FIXED BIN(31, 0);
ON ENDFILE(SYSIN) BEGIN;
PUT SKIP LIST(‘データ終了。処理件数:’ || LOOP_CNT);
STOP;
END;
/ ビルトイン関数を利用した安全な比較と加算 /
DO WHILE(‘1’B);
READ FILE(SYSIN) INTO(INPUT_REC);
/ コンパイラが最適化しやすいように演算は型を合わせる /
TOTAL_AMT = TOTAL_AMT + CAST_TO_31(INPUT_REC.PRICE);
LOOP_CNT = LOOP_CNT + 1;
END;
/ 内部関数:型変換の明示 /
CAST_TO_31: PROC(P_VAL) RETURNS(FIXED BIN(31,0));
DCL P_VAL FIXED BIN(31,0) PARM;
RETURN(P_VAL);
END CAST_TO_31;
END TEST_PROG;
なぜ「精度」が重要なのか?
PL/Iのコンパイラは、演算時に中間の型を自動的に決定する(これを`Scaling Factor`の計算と呼ぶ)。もし、あなたが異なる精度の変数同士を演算した場合、コンパイラは「情報落ち」を防ぐために、内部的に最大精度の型へ昇格させて計算を行う。
一見親切だが、これが大規模なバッチ処理で何億回と繰り返されると、CPUサイクルに無視できない負荷をかける。
- デバッグのコツ: コンパイルリストの「Attributes」セクションを必ず確認すること。そこに意図しないデータ型変換(Conversion)が頻発していないか? 予期せぬ中間ワークエリアが生成されていないか? それをチェックするだけで、パフォーマンス・チューニングの半分は完了したようなものだ。
最後に:エンジニアとしての矜持
PL/Iは古い言語だと言われる。だが、ハードウェアの境界、メモリの配置、演算のビット数までをこれほど精緻に制御できる言語は、現代の高級言語にはほとんど存在しない。
VSAMのレコードレイアウトを設計する際、`FIXED BIN(15)`と`FIXED BIN(31)`を適切に使い分けることは、単なる節約ではない。それは、システムが長年安定して稼働するための「土台」を作る行為なのだ。
予約語がない自由な世界で、あえて自分の中に厳しい規律(コーディング標準)を設ける。それが、真のメインフレーム・アーキテクトへの第一歩だ。次回の改修時には、ぜひ宣言部をもう一度見直してみてほしい。君のコードは、もっと速く、もっと美しくなれるはずだ。
