2008年10月10日星期五

异常的性能及抛出(Exception Throwing)

1. 抛出异常(Exception Throwing)
抛出异常在这篇文章里被定义为是对执行失败时给出的定义。执行失败在任何时候都引出了一个被设计好的程序不去做它应该做的事情。例如,如果打开一个文件的方法不能返回一个打开文件的操作给调用者,则它应该被设计成一个执行失败。
许多开发者可能已经很自然的去使用exceptions处理例如像除以0,以及为对象为null引用的过程。在framework中,expceptions被使用在复杂错误和逻辑错误中。首先,它很难去报告所有功能失败的手段,但是它被设计成对framework中所有公共方法通过抛出一个异常去报告方法的失败。
其实有各种各样的方法可以不使用异常处理,但大多数规结了两种,一种是返回一个错误的代码或者错误的模块不去执行并且返回一个错误的代码。性能的考虑在下面一节中讨论。作为一个API的设计者,我们不应该去猜测使用我们代码的开发者对我们的程序很熟悉,下面是异常的一些使用方法与规则:
1)不要返回一个错误代码。exceptions是在框架中报告错误的主要方法。
2)通过抛出异常报告执行失败。
3)  考虑终止进程。当你的程序遇到下一步执行不安全的时候,通过调用System.Environment.FailFast(.NET Framework 2.0 feature)代替抛出异常。
4) 不要在正常的控制流程中使用异常。除了系统错误,一般写代码的时候避免抛出异常。例如,在调用一个成员之前,你可以提供一个方式去检查。
ICollection collection = ...
if( !collection.IsReadOnly ){
collection.Add(additionalNumber);
}
被设计成执行其它成员的先决条件的成员被称为tester,实际工作的成员被称为doer.(在下性能的章节中有更多关于Tester-Doer Pattern的信息)。
5.  考虑性能的影响(在下面介绍)
6.  不用使用一公共的成员,它们为一个返回的值或out parameter返回异常。
7.  考虑使用异常bulder methods.它是在不同地方抛出一样异常的方法去避免代码的冗余。
class File{
string fileName;
public byte[] Read(int bytest){
if( !ReadFile(handle,bytes)){
throw NewFileIOException(...);
}
}
FileExceiption NewFileExction(...){
string description = //build localized string
return new FileExceipton(desciption);
}
}
1.2 异常和性能
在异常发生时候时候,它的性能会变慢。但是它也有可能获得好的性能当中止执行错误代码的时候。在下面我就介绍一下这两个情况:
1) 不要使用错误代码,因为异常引起了性能过慢
Tester-Doer模式
有时候,抛出异常的性能的成员能通过将其自身折成两个来提高性能,让我们来看看下面的例子:
Dictionary table = new Dictionary();
...
int value = table["key"];
如果the key不存在,则这个索引器将引出一个异常而引起一些性能问题。我们将其改成
Dictionary talbe = new Dictionary();
...
if( table.Contains("key") ){
int value = table["key"];
}
table成员使用了测试条件,在我们的例子中是Contains方法,这个被称作为'tester',下面一个用于操作的方法的成员就叫做Doer。这就是Tester-Doer 模式。考虑使用Tester-Doer模式去避免与异常有关的性能问题。
TryParse模式
对于极高性能要求的API,则一个更快的模式应该被使用。例如,DateTime有一个方法Parse方法去将日期转换为string,还定义了别外一个TryParse方法也是做同样的事情,但是两者的区别在于,前者失败的话会抛出一个异常,而后者失败的情况下返回一个false.
本人观点:
上面的观点来自于krzysztof cwalina的ExceptionThrowing,可能大家看的有得迷糊,翻译得不是很理想。望大家见谅。就我的理解,文章中提到几个重要的地方那就是,如果要使用抛出异常,尽量使用系统自带的。如果在程序中,尽量在可能出现异常的地方使用Tester-doea和Tryxxx方法去控制异常,毕竟程序性能是第一.
英文地址(引用):Exception Throwing
  参考地址:The Cost of Exceptions

没有评论: