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 しか記述できません。 固定値に基づいてジャンプ テーブルをコンパイルします。