0

私は入れ子になった try/catch ステートメントについて考えてきましたが、JIT がコンパイルされた IL の最適化または単純化を実行できる条件があるとすれば、それについて考え始めました。

説明のために、例外ハンドラの次の機能的に同等の表現を考えてみましょう。

// Nested try/catch
try
{
  try
  {
    try
    {
      foo();
    }
    catch(ExceptionTypeA) { }
  }
  catch(ExceptionTypeB) { }
}
catch(ExceptionTypeC) { }

// Linear try/catch
try
{
  foo();
}
catch(ExceptionTypeA) { }
catch(ExceptionTypeB) { }
catch(ExceptionTypeC) { }

ネストされた try ステートメントのスタック フレーム内に追加の変数参照や関数呼び出しがないと仮定すると、JIT は、スタック フレームが線形の例に折りたたまれている可能性があると結論付けることができますか?

では、次の例はどうでしょうか。

void Try<TException>(Action action)
{
  try
  {
    action();
  }
  catch (TException) { }
}

void Main()
{
  Try<ExceptionC>(Try<ExceptionB>(Try<ExceptionA>(foo)));
}

JIT がデリゲート呼び出しをインライン化する方法はないと思うので、この例を前の例に還元することはできません。ただし、 をfoo()スローExceptionCした場合、線形の例と比較して、このソリューションのパフォーマンスは低下しますか? フレームに含まれる余分なデータは最小限ですが、デリゲートの呼び出しからスタック フレームを破棄するには余分なコストがかかると思います。

4

2 に答える 2

8

最初のケースでは、catch ブロック内で何もしていない場合にのみ機能的に同等であることに注意してください。それ以外の場合は、次のことを考慮してください。

try
{
    foo();
}
catch (IOException)
{
    throw new ArgumentException(); // Bubbles up to caller
}
catch (ArgumentException)
{
    Console.WriteLine("Caught");
}

try
{
    try
    {
        foo();
    }
    catch (IOException)
    {
        throw new ArgumentException(); // Caught by other handler
    }
}
catch (ArgumentException)
{
    Console.WriteLine("Caught");
}

この場合、違いは明らかですが、catch ブロックが何らかの任意のメソッドを呼び出す場合、何がスローされるかを JIT はどのように知るのでしょうか? 用心するのが一番。

これにより、JIT が空の catch ブロックに対して最適化を実行するオプションが残されます。これは、そもそも推奨されない方法です。私は、JIT が悪いコードを検出して実行速度をわずかに上げようとして時間を費やすことを望んでいません。そもそもパフォーマンスに違いがあるのであれば。

于 2009-07-10T07:16:09.700 に答える
4

パフォーマンスに関する try/catch/finally 領域についての私の理解は、そのような領域はコードの通常の実行に対して透過的であるということです。つまり、コードがキャッチする例外をスローしない場合、try/catch/finally 領域はコード実行パフォーマンスにゼロの影響を与えます。

ただし、例外が発生すると、ランタイムは、発生したサイトからスタックを調べ始め、メタデータのテーブルをチェックして、問題のサイトが重要な try ブロックのいずれかに含まれているかどうかを確認します。ハンドラーが見つかった場合 (そして、適切な catch ブロックまたは finally ブロックがある場合)、関連するハンドラーが識別され、実行はこのポイントに分岐します。

例外を発生させて処理するプロセスは、パフォーマンスの観点から見るとコストがかかります。プログラマーは、例外的な状況以外でプログラム フローを通知または制御する方法として例外を使用しないでください (しゃれが意図されています)。

于 2009-07-13T07:21:11.847 に答える