3

私はここで技術的な疑問を持っています、switchステートメントはより速く実行されます、それは私が知っていることです

しかし、私が知りたいのは、 if & else if よりも速く実行する方法です。

すべてのケースの中からcontrolExpressionの適切なケースを直接見つけるにはどうすればよいですか?

if else if itself を実行して適切なケースを見つけることを使用して記述されていると仮定すると、より高速に実行されるべきではなく、else if の場合と同じように実行されますか?

答えてもらえますか?前もって感謝します

4

1 に答える 1

5

ステートメントは基本的switchに、すべてのケースに対して同じ種類の比較を実行します: var == avar == bvar == cなど。

このページには、コンパイラによってアセンブリに変換される方法の詳細が記載されていますが、基本的に 3 つの「種類」の switch ステートメントがあります。

  1. switch連続するcase整数を含むステートメント- などcase 3: ... case 4: ... case 5: ...。このような場合、コンパイラはジャンプ テーブルを作成できます。これは、メモリの連続ブロック内でジャンプするアドレスのリストであり、オフセットを計算し、アドレスを見つけてジャンプするだけです。if-else ifこれは型チェーンよりも高速です。(もちろん、ケースが 1 つしかない場合は少し遅くなります。)
  2. switch一見ランダムなcase整数を含むステートメント- などcase 12: ... case 106: ... case 9: ...if-else ifこのような場合、コンパイラはチェーンを構築するだけなのでif-else if、コードのタイプよりも高速になることはありません。
  3. switch一見ランダムなcase整数を含むステートメント- かなりの数がある場合、一部のコンパイラはすべてのケースに対してバイナリ検索ツリーを構築するためO(log(n))、特定のブランチを実行する時間があり、コードのパフォーマンスが向上します。(ツリーのどのブランチに従うべきか、またはジャンプする必要があるかどうかをチェックする余分なオーバーヘッドがあるため、コンパイルしているアーキテクチャに大きく依存します。)

これは、コンパイラの裏をかくことができる状況です: ケースが のような方程式によってのみ一致することがわかっている場合は3x+5、関数ポインターの配列を作成し、インデックス ( (caseNum - 5) / 3) を計算してから、それを実行できます。スタイルの受け渡し (または、人々をバティに駆り立てたい場合は、同じ計算を実行してラベルの配列を作成し、スパゲッティ スタイルにジャンプします。どちらの方法でも、分岐時間gotoで最適な「連続ケース」スタイルのアセンブリが得られます。O(1)

于 2012-04-25T16:44:10.093 に答える