托管异常的性能

本文通过测试不同数量的异常抛出次数,展示了异常处理在.NET平台上的性能表现。结果显示,在一定范围内异常处理对性能的影响较小,但当异常数量增加到一定程度时,性能消耗显著提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们先来看看下面代码的执行效果:
下述代码中,依次扔出指定个数的异常,并显示这样做所花费的时间:

之前用的DateTime方式测试的数字不是很准确,下面做个修改,改成用System.Diagnostics.Stopwatch来测试所花费时间

    class Program
    {
        static void Main(string[] args)
        {
            ThrowException(1);
            ThrowException(2);
            ThrowException(3);
            ThrowException(4);
            ThrowException(5);
            ThrowException(10);
            ThrowException(25);
            ThrowException(50);
            ThrowException(100);
            ThrowException(250);
            ThrowException(1000);

            Console.ReadLine();
        }

        private static System.Diagnostics.Stopwatch stopwatch = 
            new System.Diagnostics.Stopwatch();

        static void ThrowException(int num)
        {
            Console.WriteLine(num);
            stopwatch.Reset();
            stopwatch.Start();
            for (int i = 0; i < num; i++)
            {
                try
                {
                    throw new Exception("test Exception");
                }
                catch (Exception)
                {
                }
            }
            stopwatch.Stop();
            Console.WriteLine(stopwatch.Elapsed);
            Console.WriteLine("**************************************");
        }

    }


下述执行值是在我公司台式机上的执行值: 我公司台式机配置(AMD 64 位3000+ CPU, 2GB RAM,Win2003 64 为操作系统)

1
00:00:00.0063479
**************************************
2
00:00:00.0121209
**************************************
3
00:00:00.0127166
**************************************
4
00:00:00.0153518
**************************************
5
00:00:00.0174371
**************************************
10
00:00:00.0409867
**************************************
25
00:00:00.0914862
**************************************
50
00:00:00.1799064
**************************************
100
00:00:00.3761265
**************************************
250
00:00:00.9225065
**************************************
1000
00:00:03.7062995
**************************************

由上可以看到,如果单位时间内产生异常数在某一个值范围内,异常的性能几乎可以忽略不计。而且花费时间几乎都一样。
但是,一旦超过这个阈值,则开始根据异常数翻倍需要处理的时间。

原因:

CLR 中的错误处理是借助结构化异常处理实现的。
引发托管异常之前,托管异常的开销非常小。
在 CLR 中,引发异常时,需要使用堆栈遍历为已引发的异常找到相应的异常处理程序。
堆栈遍历是一种开销较大的操作。
正如它的名称所表示的,异常应该用于异常或意外的情况,而不应该用于业务逻辑处理。

堆栈遍历的工作实际上就是从当前调用帧开始,反向遍历所有的堆栈帧,
处理能够处理的,跳过不能处理的,最终到栈顶结束遍历。

异常的工作原理,请参看有关结构化异常处理(Structured Exception Handling,SEH)的知识。

相关资料:

深入研究 Win32 结构化异常处理
http://vicchina.51.net/research/other/seh/crashcourse/intro.htm
http://vicchina.51.net/show_article.php?id=63

对于结构化异常处理(SEH)的进一步探索
http://vicchina.51.net/show_article.php?id=64

NT 中的异常帧结构和异常嵌套
http://vicchina.51.net/show_article.php?id=65

Under the hood: 从Win32 SEH到CLI异常处理模型
http://www.cnblogs.com/neoragex2002/archive/2006/04/16/376402.html

CLR 中代码访问安全检测实现原理
http://www.blogcn.com/user8/flier_lu/blog/3692778.html

A Crash Course on the Depths of Win32 Structured Exception Handling
http://www.microsoft.com/msj/0197/exception/exception.aspx
http://www.xfocus.net/articles/200503/785.html
http://www.bluedon.com/bluedo621/search/newsdisplay3.asp?id=1612&sort=3

由一个性能问题引出的.net概念
http://blog.youkuaiyun.com/lornshrimp/archive/2004/01/02/18878.aspx

编写高性能的托管应用程序:入门
http://www.microsoft.com/china/msdn/archives/library/dndotnet/html/highperfmanagedapps.asp#highperfmanagedapps_topic12

异常和性能
http://msdn2.microsoft.com/zh-CN/library/ms229009.aspx

异常设计准则
http://msdn2.microsoft.com/zh-CN/library/ms229014.aspx

异常性能计数器 
http://msdn2.microsoft.com/zh-cn/library/kfhcywhs.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值