ApexコードのCPU使用量を最適化するためのベストプラクティス


SalesforceのCPU時間(CPU Time)は、Apexコードが消費したサーバーリソースを測定する指標であり、トランザクションごとに制限が設定されています。同じコードを実行しても、CPU時間が変動することがあります。この現象を理解し、安定したコード実行を実現する方法を解説します。


CPU時間が変動する理由と背景

  1. マルチテナントアーキテクチャ
    Salesforceは複数の組織が共有するマルチテナント型のプラットフォームです。他のテナントの負荷やシステムリソースの利用状況により、CPU時間にばらつきが生じます。

  2. ガベージコレクションの影響
    実行中に不要なオブジェクトを解放するためのガベージコレクションが自動で発生します。この処理タイミングにより、わずかにCPU時間が変動します。

  3. データやメタデータの状態
    実行時に使用されるデータ量やインデックスの有無、メタデータの複雑さがパフォーマンスに影響を与えます。例えば、SOQLクエリが複雑な条件を含む場合、余分な処理が発生する可能性があります。

  4. 非同期処理やバックエンド要因
    Salesforce内部で非同期的に処理されるタスク(SOQL、DML、その他のAPI呼び出しなど)は、リソースの利用状況によって変動します。

  5. 実行パスの違い
    条件分岐やループによってコードの実行パスが異なると、使用するCPU時間が変わることがあります。特に、データセットが大規模な場合に顕著です。


CPU時間を安定させるベストプラクティス

  1. 効率的なクエリ設計

    • 必要なデータだけを取得するようにSOQLを最適化。
    • 適切なインデックスを利用し、不要な条件式を避ける。
  2. DML操作のバルク化

    • 単一トランザクション内でのDML操作回数を最小限に抑える。
    • トリガーやプロセスビルダーのロジックを最適化する。
  3. 非同期処理の活用

    • Queueable ApexやBatch Apexを使用して、大量の処理を分割。
  4. システムリソースの監視

    • `Limits.getCpuTime()` をコード内で使用して、CPU時間を動的にモニタリング。
    • 事前にしきい値を超える可能性のある箇所を特定し、処理を分割。
  5. テスト環境での負荷試験

    • 本番環境に近いデータ量や構成を用いてテストを行い、問題箇所を特定。

CPU時間の限界を理解する

Salesforceでは、1トランザクションあたりのCPU時間に制限があります。この制限を超えると、`System.LimitException`がスローされます。制限内でコードを効率的に実行することが求められます。


コード例:CPU時間の計測と対応

以下は、CPU時間を動的にチェックし、効率化を図るための例です。

public class CpuTimeExample {
    public void processRecords(List<SObject> records) {
        Integer cpuLimit = Limits.getCpuTime();
        for (SObject record : records) {
            if (Limits.getCpuTime() - cpuLimit > 1000) { // 1秒の余裕を持たせる
                System.debug('CPU時間の制限に近づいています。処理を中断します。');
                break;
            }
            // 処理ロジック
            update record;
        }
    }
}

コメント