C の switch ステートメントのオーバーヘッド

Switch ステートメントは、連続する値の場合はジャンプ テーブルにコンパイルされ、スパース値の場合は一連の if-else ステートメントにコンパイルされます。いずれにせよ、パフォーマンスを気にする場合は、画像処理の内側のループに switch ステートメントは必要ありません。代わりに以下のようにします。

また、重みの計算を内側のループの外に移動したことに注意してください (これを実現するためにケース 2 のループを交換しました)。内側のループから何かを移動するこのタイプの考え方により、C から必要なパフォーマンスが得られます。

switch (mode)                  /* select the type of calculation */
{
case 0:
    weight = dCentre / maxDistanceEdge;
    for (x = 0; x < width; x++) {
        for (y = 0; y < height; y++) {
             // Calculate the new pixel value given the weight
             ...
        }
    }
    break;
case 1:
    for (x = 0; x < width; x++) {
        weight = (float)x/width;
        for (y = 0; y < height; y++) {
             // Calculate the new pixel value given the weight
             ...
        }
    }
    break;
case 2:
    // note - the loops have been swapped to get the weight calc out of the inner loop
    for (y = 0; y < height; y++) {
        weight = (float)y/height;
        for (x = 0; x < width; x++) {
             // Calculate the new pixel value given the weight
             ...
        }
    }
    break;
case 3:
    weight = dBottomLeft / maxDistanceCorner;
    for (x = 0; x < width; x++) {
        for (y = 0; y < height; y++) {
             // Calculate the new pixel value given the weight
             ...
        }
    }
    break;
case 4:
    weight = dTopRight / maxDistanceCorner;
    for (x = 0; x < width; x++) {
        for (y = 0; y < height; y++) {
             // Calculate the new pixel value given the weight
             ...
        }
    }
    break;
default:
    weight = 1;
    for (x = 0; x < width; x++) {
        for (y = 0; y < height; y++) {
             // Calculate the new pixel value given the weight
             ...
        }
    }
    break;

// etc..
}

コードサイズよりも効率が重要な場合は、はい、冗長ルーチンを作成する必要があります。 case ステートメントは、C で実行できるオーバーヘッドの少ないものの 1 つですが、ゼロではありません。モードに基づいて分岐する必要があるため、時間がかかります。本当に最大のパフォーマンスが必要な場合は、ループを複製するという犠牲を払っても、ケースをループから外してください。


Switch ステートメントは、可能な限り効率的です。それらはジャンプ テーブルにコンパイルされます。実際、これが switch が制限されている理由です。できる switch しか記述できません。 固定値に基づいてジャンプ テーブルをコンパイルします。