優れたコンパイラは、ジャンプ テーブル、チェーンされた if/else、またはその組み合わせのいずれかを選択できます。設計が不十分なコンパイラは、そのような選択をしない可能性があり、スイッチ ブロックの非常に悪いコードを生成することさえあります。しかし、適切なコンパイラであれば、スイッチ ブロックの効率的なコードを生成する必要があります。T
ここでの主な決定要因は、数値が大きく離れている場合にコンパイラが if/else を選択する可能性があることです [そして、自明ではなく (たとえば、2、4、8、16、256 などで除算すると) より近い値に変更されます]。
switch(x)
{
case 1:
...
case 4912:
...
case 11211:
...
case 19102:
...
}
少なくとも 19102 * 2 バイトのジャンプ テーブルが必要です。
一方、数値が互いに接近している場合、コンパイラは通常、ジャンプテーブルを使用します。
たとえそれif/else
が設計のタイプであっても、通常は「二分探索」を行います - 上記の例を取ると:
if (x <= 4912)
{
if (x == 1)
{
....
}
else if (x == 4912)
{
....
}
} else {
if (x == 11211)
{
....
}
else if (x == 19102)
{
...
}
}
ケースがたくさんある場合、このアプローチは非常に深くネストされ、人間はおそらく 3 ~ 4 レベルの深さで迷子になるでしょう (それぞれが範囲の MIDDLE のある時点から始まることに注意してください)。 log2(n) によるテストの数。ここで、n は選択肢の数です。それは確かに単純なアプローチよりもはるかに効率的です
if (x == first value) ...
else if (x == second value) ...
else if (x == third value) ...
..
else if (x == nth value) ...
else ...
特定の値が if-else チェーンの先頭に置かれている場合、これはわずかに改善される可能性がありますが、それは、コードを実行する前に最も一般的な値を判断できることを前提としています。
ケースにとってパフォーマンスが重要な場合は、2 つの代替案をベンチマークする必要があります。しかし、私の推測では、コードをスイッチとして記述するだけで、コードがより明確になり、同時に、高速ではないにしても、少なくとも同じ速度で実行されると思います。