1. ホーム
  2. c#

[解決済み】例外をスローしない場合、try/catchブロックはパフォーマンスを低下させるか?

2022-03-28 01:52:42

質問

マイクロソフトの社員とコードレビューをしているときに、あるコードの大きなセクションが try{} ブロックがあります。彼女とIT担当者は、これがコードのパフォーマンスに影響を与える可能性があることを示唆しました。実際、彼らはコードの大部分をtry/catchブロックの外に置き、重要な部分のみをチェックすることを提案しました。マイクロソフトの社員はさらに、近々発表されるホワイトペーパーで、誤ったtry/catchブロックに対して警告していると述べました。

いろいろと調べてみると は最適化に影響を与える可能性があります しかし、それは変数がスコープ間で共有されている場合にのみ適用されるようです。

私はコードの保守性や正しい例外処理について尋ねているのではありません(問題のコードは間違いなくリファクタリングが必要です)。また、フロー制御のために例外を使用することについても言及していません。これはほとんどの場合、明らかに間違っています。これらは重要な問題ですが(より重要なものもあります)、ここでの焦点ではありません。

例外が発生した場合、try/catchブロックはパフォーマンスにどのような影響を与えるのでしょうか? ではなく を投げることができますか?

解決方法は?

確認してください。

static public void Main(string[] args)
{
    Stopwatch w = new Stopwatch();
    double d = 0;

    w.Start();

    for (int i = 0; i < 10000000; i++)
    {
        try
        {
            d = Math.Sin(1);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }

    w.Stop();
    Console.WriteLine(w.Elapsed);
    w.Reset();
    w.Start();

    for (int i = 0; i < 10000000; i++)
    {
        d = Math.Sin(1);
    }

    w.Stop();
    Console.WriteLine(w.Elapsed);
}

出力します。

00:00:00.4269033  // with try/catch
00:00:00.4260383  // without.

ミリ秒単位。

449
416

新しいコードです。

for (int j = 0; j < 10; j++)
{
    Stopwatch w = new Stopwatch();
    double d = 0;
    w.Start();

    for (int i = 0; i < 10000000; i++)
    {
        try
        {
            d = Math.Sin(d);
        }

        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }

        finally
        {
            d = Math.Sin(d);
        }
    }

    w.Stop();
    Console.Write("   try/catch/finally: ");
    Console.WriteLine(w.ElapsedMilliseconds);
    w.Reset();
    d = 0;
    w.Start();

    for (int i = 0; i < 10000000; i++)
    {
        d = Math.Sin(d);
        d = Math.Sin(d);
    }

    w.Stop();
    Console.Write("No try/catch/finally: ");
    Console.WriteLine(w.ElapsedMilliseconds);
    Console.WriteLine();
}

新しい結果です。

   try/catch/finally: 382
No try/catch/finally: 332

   try/catch/finally: 375
No try/catch/finally: 332

   try/catch/finally: 376
No try/catch/finally: 333

   try/catch/finally: 375
No try/catch/finally: 330

   try/catch/finally: 373
No try/catch/finally: 329

   try/catch/finally: 373
No try/catch/finally: 330

   try/catch/finally: 373
No try/catch/finally: 352

   try/catch/finally: 374
No try/catch/finally: 331

   try/catch/finally: 380
No try/catch/finally: 329

   try/catch/finally: 374
No try/catch/finally: 334