【実務・中級編】INDEX関数による検索アルゴリズムとパフォーマンス – PL/Iの基本構文とデータ制御実践ガイド

メインフレーム技術の深淵:INDEX関数と戦う「文字列検索」の最適化

諸君、お疲れ様だ。現場のバッチ改修で、何万件というVSAMレコードを相手に「文字列検索」を繰り返すロジックに頭を抱えた経験はないだろうか?

今日は、PL/Iにおける`INDEX`関数の挙動と、大規模データ処理における「見えないコスト」について話をしよう。教科書的なリファレンスをなぞるだけなら誰にでもできる。我々ベテランが気にするのは、その先にあるプロセッササイクルと、デバッグの夜を短くするための「防衛的コーディング」だ。

1. INDEX関数の「戻り値0」をどう扱うか

まず基本の確認だ。`INDEX(string, pattern)` は、第一引数の中に第二引数が最初に出現する位置を返す。見つからなければ「0」だ。

この「0」という値、単なる不一致のフラグとして処理するのは当然だが、バッチ処理では「0が返る確率が高いのか、低いのか」で設計思想を変える必要がある。

例えば、レコードの特定のフィールドから特定のセパレータを探す際、全件で見つかることを前提とした処理と、稀にしか現れない例外を検索する処理では、実行時のパイプライン効率がまるで違う。戻り値が0であるという事実は、単なる失敗ではなく、「後続の文字列操作(SUBSTRなど)をスキップすべき重要な分岐点」であることを忘れてはならない。

2. 実践コード:VSAMレコード走査のベストプラクティス

現場でよく見る「動かないコード」は、例外処理を`ON`ユニットや複雑な`IF`で囲い込みすぎて、メインのロジックが見えなくなっているものだ。以下に、可読性とパフォーマンスを両立させた実務的な実装例を示す。

1
/ ————————————————————- /
/ プログラム名: SEARCH_DEMO /
/ 処理概要: VSAM入力から特定のキーワードを抽出する /
/ ————————————————————- /
SEARCH_PROC: PACKAGE;

SEARCH_MAIN: PROCEDURE OPTIONS(MAIN);

DCL REC_IN CHAR(200); / VSAMから読み込んだレコード /
DCL KEY_POS FIXED BIN(15); / INDEX関数の戻り値保持用 /
DCL SEARCH_KEY CHAR(10) INIT(‘ERROR-CODE’);

/ 組み込み関数の明示的宣言 /
DCL INDEX BUILTIN;

/ 疑似的なVSAM読み込みループ /
DO WHILE(EOF_FLAG = ‘0’);
READ FILE(INFILE) INTO(REC_IN);

/

  • INDEX関数は最適化されているが、ループ内で無駄な計算をしない。
  • 見つからなかった場合(0)のハンドリングをIF文の先頭で完結させる。

/
KEY_POS = INDEX(REC_IN, SEARCH_KEY);

IF KEY_POS = 0 THEN DO;
/ 該当なしの場合は即座に次へ(ネストを深くしない) /
ITERATE;
END;

/

  • 見つかった場合の処理:
  • ここでSUBSTRを使う際は、KEY_POSの妥当性を再度確認せよ。
  • 大規模データでは、メモリを無駄に確保しないよう注意すること。

/
CALL PROCESS_FOUND_DATA(SUBSTR(REC_IN, KEY_POS, 20));

END;

END SEARCH_MAIN;
END SEARCH_PROC;

3. 大規模データにおけるパフォーマンスの勘所

数百万件のレコードを処理する場合、`INDEX`関数単体の速度よりも、「どのメモリ領域をスキャンさせているか」が重要になる。

  • 無駄なスキャンを避ける: 固定長のVSAMレコードなら、必要な範囲だけを`SUBSTR`で切り出してから`INDEX`をかける方が、レコード全体(200バイトなど)を毎回走査するより圧倒的に速い。
  • BUILTINの活用: `INDEX`はコンパイラによって機械語レベルで最適化される。自前で`DO`ループを回して文字比較を行うような「車輪の再発明」は、現代のメインフレーム環境では最も忌むべき行為だ。
  • ONユニットとの距離感: `INDEX`の失敗(0)を`ON`ユニットで拾おうなどと考えてはいけない。あれはシステム的な例外のためのものだ。制御フローの中に「見つからない場合」を組み込むのが、最も保守性の高い設計だ。

最後に:諸君へのアドバイス

PL/Iのコードを美しく保つ秘訣は、「計算の意図」と「計算の実行」を分離することだ。`INDEX`を使って何かを探すとき、それが「単なるデータのチェック」なのか、「業務ロジックの分岐点」なのかをコード上で明確にコメントせよ。

後任の担当者が深夜3時の障害対応でソースを見たとき、そのコメントが命綱になる。現場のエンジニア諸君、効率的かつ「人間が理解できる」ロジックを追求し続けてくれ。

何か特定のアルゴリズムで詰まったら、またいつでも相談に来るといい。道は開けるはずだ。

タイトルとURLをコピーしました