Overhead of try/finally in C#?

后端 未结 6 1246
有刺的猬
有刺的猬 2020-12-07 23:47

We\'ve seen plenty of questions about when and why to use try/catch and try/catch/finally. And I know there\

6条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-08 00:18

    Let's actually put some benchmark numbers to this. What this benchmark shows is that, indeed, the time of having a try/finally is about as small as the overhead of a call to an empty function (probably better put: "a jump to the next instruction" as the IL expert stated it above).

                static void RunTryFinallyTest()
                {
                    int cnt = 10000000;
    
                    Console.WriteLine(TryFinallyBenchmarker(cnt, false));
                    Console.WriteLine(TryFinallyBenchmarker(cnt, false));
                    Console.WriteLine(TryFinallyBenchmarker(cnt, false));
                    Console.WriteLine(TryFinallyBenchmarker(cnt, false));
                    Console.WriteLine(TryFinallyBenchmarker(cnt, false));
    
                    Console.WriteLine(TryFinallyBenchmarker(cnt, true));
                    Console.WriteLine(TryFinallyBenchmarker(cnt, true));
                    Console.WriteLine(TryFinallyBenchmarker(cnt, true));
                    Console.WriteLine(TryFinallyBenchmarker(cnt, true));
                    Console.WriteLine(TryFinallyBenchmarker(cnt, true));
    
                    Console.ReadKey();
                }
    
                static double TryFinallyBenchmarker(int count, bool useTryFinally)
                {
                    int over1 = count + 1;
                    int over2 = count + 2;
    
                    if (!useTryFinally)
                    {
                        var sw = Stopwatch.StartNew();
                        for (int i = 0; i < count; i++)
                        {
                            // do something so optimization doesn't ignore whole loop. 
                            if (i == over1) throw new Exception();
                            if (i == over2) throw new Exception();
                        }
                        return sw.Elapsed.TotalMilliseconds;
                    }
                    else
                    {
                        var sw = Stopwatch.StartNew();
                        for (int i = 0; i < count; i++)
                        {
                            // do same things, just second in the finally, make sure finally is 
                            // actually doing something and not optimized out
                            try
                            {
                                if (i == over1) throw new Exception();
                            } finally
                            {
                                if (i == over2) throw new Exception();
                            }
                        }
                        return sw.Elapsed.TotalMilliseconds;
                    }
                }
    

    Result: 33,33,32,35,32 63,64,69,66,66 (milliseconds, make sure you have code optimization on)

    So about 33 milliseconds overhead for the try/finally in 10 million loops.

    Per try/finally then, we are talking 0.033/10000000 =

    3.3 nanoseconds or 3.3 billionth of a second overhead of a try/finally.

提交回复
热议问题