所以我对它的c#侧感兴趣 - 但我正在标记c ++,因为那里存在概念而我并没有超过'finally'关键字。 所以无论如何 - 在线是否存在关于try-catch如何减速或将使用更多内存而不是简单的'if-else'或其他代码的基准测试?例如,现在我正在编写一个代码并使用Streamwriter,当你把鼠标放在它上面时会显示7个可能的例外...所以有人会声称如果我写下这样的话会更快:
//////////////
if(path is not too long)
{ if(file exists)
{ if(nothing else uses the file)
{ if(user is authorized)
}}}
////////////
你有7个条件,你可以使用try-catch - 更不用说这些条件不能简化为单个if语句。
10倍!
答案 0 :(得分:6)
try
/ catch
会有轻微的性能成本,但与文件访问相比,成本并不值得担心。
更重要的是try
/ catch
是正确的,嵌套的if不是,因为文件系统是可以异步修改的共享资源。处理实际打开文件的错误或异常结果是避免竞争条件的唯一方法。
见
这些示例都使用文件,但这里有共享资源的一般原则。
答案 1 :(得分:1)
任何性能差异都不是重点。
在打开文件之前测试文件是否存在,并不能保证另一个线程或进程没有删除或锁定文件;无论你是否成功,你只知道试图打开它。因此,OS调用通常返回成功或失败代码,或返回已知值以指示无效的文件句柄。
在面向对象的环境中,使用创建对象获取资源(RAII)的习惯用法更简洁,然后必须抛出异常而不是允许创建无效对象。或者,你可以有一个面向对象的OS接口,它返回对已知坏对象的引用(例如null),但是你将异常延迟到程序中的后一点,因此可能不知道哪个文件无法打开
另一个优点是,它允许提供对象的库来决定其有效性的条件 - 如果文件实际上是指向WebDav服务器的链接,那么其他条件(如存在有效的网络接口)需要。通过让库来处理这些条件,实现细节对客户端代码是隐藏的(这适用于库API,以便尝试/捕获)
答案 2 :(得分:0)
关于异常处理及其后果(无论是成本,系统稳定性等)的真正精彩话语,我建议阅读第二章 “通过C#CLR” 杰弗里里希特 。它肯定会回答您的大部分问题并帮助理解.NET框架如何处理漏洞,以及如何使用Performance Counter作为评估代码抛出异常影响的方法。
使用Guard子句(正如您在问题中提到的)不是异常处理的替代方法,它们是两个互补的概念。诸如if(file exists)
之类的保护条件可能会使其余条件短路并产生更好的性能,因为您的代码可能不需要测试以下条件,即if(user is authorized)
可能是资源密集型或耗时的。