浅测Try&Catch的性能到底有多差(2)
Hello,我是Snake,欢迎阅读我的文章--浅测Try&Catch的性能到底有多差(2)
昨晚因为快要熄灯断电的缘故,发表上一篇文章有些仓促.在昨晚熄灯之后我考虑到算法可以简化,于是今早放学之后就马上回来改了改算法.代码如下:
public class MyClass
{
public static void Main()
{
int maxLine=30000;
int[][] ns=new int[maxLine][];
Stopwatch sw=new Stopwatch();
sw.Reset();
sw.Start();
for(int i=0;i<maxLine;i++)
{
ns[i]=new int[i+1];
ns[i][0]=1;
for(int j=1;j<=i;j++)
{
if(j==i)
{
ns[i][j]=1;
continue;
}
else
{
ns[i][j]=ns[i-1][j-1]+ns[i-1][j];
}
/*
try
{
ns[i][j]=ns[i-1][j-1]+ns[i-1][j];
}
catch(Exception ex)
{
ns[i][j]=1;
}
}
*/
}
sw.Stop();
Console.WriteLine(sw.Elapsed.ToString());
Console.ReadLine();
}
}
最后执行10000行的时间缩短了0.1~0.15秒.但这显然不是我现在要阐述的论题.
在上一篇文章我并未提出我的平台和操作系统,这显然是对测试的一种不尊重,所以赶紧放上我的测试环境详情:
操作系统:windows 7 Ultimate
主板芯片组: A780G(超级缩水版)
CPU:AMD X2 2700MHZ(5000+黑盒)
内存:4G(金士顿 ddr2 800 2G*2)
还好我没有高估我的内存.刚才想提高测试的函数,于是在10000后面加了个零,差点没把我电脑给搞歇菜了.于是只再加了20000行.那么现在在改进了算法和行数之后他们的效率又会是如何呢?
ps:这算法明显给if和else减少压力从原来的四段变为两段,而try&catch负担依旧很重.另外我就不截图了,截图太麻烦,而且我之准备让程序在运行期间只执行2次,并不是原先的5次,可能是程序内存占用的原因吧,每次运行时间都相继减少,而且内存也吃不消,30000行1趟占用2G左右的内存.
下面是if&else方式执行30000行的记录:
1.1 30000lines 2.956s
1.2 30000lines 3.751s
2.1 30000lines 2.826s
2.2 30000lines 3.619s
3.1 30000lines 3.068s
3.2 30000lines 3.306s
现在是try&catch方式执行30000行的记录:
1.1 30000lines 7.611s
1.2 30000lines 7.813s
2.1 30000lines 6.804s
2.2 30000lines 7.064s
3.1 30000lines 6.945s
3.2 30000lines 7.036s
这次虽然算法偏向了if&else,但是最终的结果并没有跟try&catch拉开更大的距离,反而缩小了一倍.
在执行30000行测试的时候发现内存占用特别厉害,将近100%,可能是在这方面遇上瓶颈,于是我缩减10000行代码再试试看.
1.1 20000lines 1.430s
1.2 20000lines 1.755s
2.1 20000lines 1.404s
2.2 20000lines 1.851s
3.1 20000lines 1.410s
3.2 20000lines 1.764s
现在是try&catch方式执行30000行的记录:
1.1 20000lines 3.536s
1.2 20000lines 4.092s
2.1 20000lines 3.613s
2.2 20000lines 4.103s
3.1 20000lines 3.558s
3.2 20000lines 4.080s
我郁闷了.不过也没关系,事实已经证明了try&catch是性能低下的东西.
本节总结:
本节使用杨辉三角的优化(较前一节)算法,并且提升了运算量,但结果if&else的优势反而变小了,先不管原因是什么,以后您还会在代码中大量的"踹"一下再"咔吃"一下吗?事实上很多异常都可以提前判断,特别是"引用类型是否为空"和指定格式"是否为预期类型"的判断基本上不需要使用try&catch块,特别在大量的循环中.
try&catch的确给我们带来方便,但它的性能也的确难以恭维,另外也降低了我们原有的编写代码的谨慎程度.所以在我个人编写的代码中一般是不会出现try&catch的,除非必要.
好了,本节也正式完成,但是因为杨辉三角的复杂度导致程序运算中try&catch发生的概率难以确定(确定是肯定可以,但是我实在懒得去验证,很久没有拿笔在草纸上计算数学问题了).那么下一节我将以一个简单算法来验证if&else和try&catch之间的性能,我们至少要确定一次循环内至少触发了多少次try和catch,或执行了多少次判断才能更精确地确定这两者的性能.那么如果您还有兴趣看下去的话,咱们就在下一篇"不见不散" : )
