web-dev-qa-db-ja.com

switchステートメントの実行時の複雑さはどのくらいですか?

nケースがあると仮定して、switchステートメントの最悪の場合の実行時の複雑さを知りたいのですが。

私はいつもO(n)だと思っていました。コンパイラが何か賢いことをするかどうかはわかりませんが。答えが実装固有のものである場合、次の言語について知りたいです。

  • Java
  • C/C++
  • C#
  • PHP
  • Javascript
42
Fragsworth

最悪のO(n)です。ときどき(これは言語とコンパイラに依存します)、ジャンプテーブルルックアップに変換されます(大文字と小文字の範囲があまり大きくない "Nice"スイッチの場合)。それがO(1)です。

コンパイラーがファンキーになりたい場合は、複雑さをその中間に実装できる方法を考えることができます(たとえば、lognの場合、ケースでバイナリ検索を実行します)。しかし実際には、線形時間または一定時間のいずれかを取得します。

39
lijie

Switchステートメントのbig-Oの複雑さは、実際には重要なポイントではありません。 Big-O表記は、nが無限大に向かって増加するときのパフォーマンスを指します。漸近的なパフォーマンスが問題になるほど大きなswitchステートメントがある場合、それは大きすぎてリファクタリングする必要があります。

読みやすさの問題は別として、JavaおよびC#では、単一のメソッドの最大サイズの内部制限にすぐに達すると思います。

頻繁に呼び出される比較的小さなswitchステートメントの場合は、代わりに使用できる他のアプローチと比較して、switchステートメントの実際のパフォーマンスを測定する方がおそらく有益です。この測定は、ループ内で操作を繰り返し実行することによって行うことができます。

大規模なswitchステートメントの場合、n =が非常に大きくなっても、ほぼO(1)パフォーマンスを持つディクショナリまたは同様のデータ構造を使用するようにリファクタリングすることをお勧めします。限られたメソッドサイズ。

16
Mark Byers

C++コンパイラは、switchステートメントをジャンプテーブルに変換できます(つまり、ジャンプオフセットの配列を作成し、値を取得して、テーブルへのインデックスとして使用します)。これはO(1)です。

C#コンパイラは、ハッシュテーブルをアセンブルできることを除いて、同様のアプローチを使用します。

10
Tim Robinson

Gccコンパイラを使用したCには、O(1) for tight range(jump table)または最悪の場合O(log N)for loose range(binary search)があります。

8
Smit Johnth

最悪のケースはO(n)かもしれませんが、少なくともC/C++のような言語ではJavaおよびC#で、ケースがコンパイル時の定数である場合、ジャンプテーブルを使用できます(およびかなり頻繁に使用されます)O(1)に複雑さを取得します。

PHPまたはJavaScriptのようなより動的な言語がジャンプテーブルを設定しようとするかどうかはわかりません。

4
Michael Burr