trycatch 如何伤害内存/CPU?
所以我对它的 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 倍!
so I am interested in the c# side of it - but I am tagging c++ as the concept exists there and I am not over the 'finally' keyword.
So anyway - are there any benchmarks online about how try-catch would slow down or will use more memory than simple 'if-else' or other code?? For instance, now I am writing a code and using Streamwriter which shows 7 possible exceptions when you hold your mouse over it...so would anyone claim that it will be faster if i write something like:
//////////////
if(path is not too long)
{ if(file exists)
{ if(nothing else uses the file)
{ if(user is authorized)
}}}
////////////
You have 7 conditions and you can use instead just try-catch - not to mention that these conditions cannot be simplified to a single if statement.
10x!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果发生异常,
try
/catch
会产生轻微的性能成本,但与文件访问相比,这个成本并不值得担心。更重要的是
try
/catch
是正确的,嵌套的 if 则不然,因为文件系统是可以异步修改的共享资源。处理实际打开文件的错误或异常结果是避免竞争条件的唯一方法。请参阅
这些示例都使用文件,但这里有一个共享资源的通用原则。
try
/catch
has a slight performance cost if the exception occurs, but compared to file access the cost is not worth worrying about.More important is that
try
/catch
is correct, the nested ifs are not, because the filesystem is a shared resource that can be modified asynchronously. Handling the error or exception result of actually opening the file is the only way to avoid a race condition.See
These examples all use files, but there's a general principle here for shared resources.
任何性能差异都不是真正的重点。
在打开文件之前的某个时刻测试文件是否存在并不能保证另一个线程或进程没有删除或锁定该文件;您只有在尝试打开它时才知道是否成功。因此,操作系统调用通常会返回成功或失败代码,或者返回已知值来指示无效的文件句柄。
在面向对象的环境中,使用创建对象获取资源的习惯用法更简洁(RAII )那么你必须抛出异常而不是允许创建无效的对象。或者,您可以有一个面向对象的操作系统接口,它返回对已知坏对象(例如 null )的引用,但随后您将异常延迟到程序中的稍后位置,因此可能不知道哪个文件无法打开。
另一个优点是,它允许提供对象的库决定其有效性的条件是什么 - 如果该文件实际上是到 WebDav 服务器的链接,则需要其他条件,例如存在有效的网络接口。通过让库处理条件,实现细节对客户端代码隐藏(这适用于库 API,如 try/catch)
Any performance differences are not really the point.
Testing that a file exists at some point before opening it does not guarantee that another thread or process has not deleted or locked the file; you only know at the point of attempting to open it whether or not you have succeeded. Hence OS calls often return success or failure codes, or return a known value to indicate an invalid file handle.
In an object oriented environment, it's cleaner to use the idiom that creating the object acquires the resource (RAII) then you have to throw an exception rather than allow an invalid object to be created. Alternatively, you could have an object-oriented OS interface which returned a reference to a known bad object ( e.g. null ), but then you're delaying the exception to a later point in the program, so may not know what file failed to open.
The other advantage is that it allows the library providing the object to decide what the conditions for its validity are - if the file were actually a link to a WebDav server say, then other conditions such as presence of a valid network interface would be required. By having the library take care of the conditions, the implementation details are hidden from the client code (this applies to library APIs as to try/catch)
对于关于异常处理及其后果(无论是成本、系统稳定性等)的真正精彩的讨论,我建议阅读伟大著作的第 20 章“CLR via C#” > 作者:杰弗里·里希特。它肯定会回答您的大多数问题,并帮助您了解 .NET 框架如何在幕后处理异常,以及如何使用性能计数器作为评估代码引发的异常影响的方法。
使用保护子句(正如您在问题中提到的)并不是异常处理的替代方法,它们是两个互补的概念。诸如
if(文件存在)
之类的保护条件可能会短路其余条件并产生更好的性能,因为您的代码可能不需要测试以下条件,即if(用户已授权)
可能是资源密集型或耗时的。For a truly brilliant discourse on Exceptions handling and its ramifications (be it cost, system stability, etc..) I recommend reading Chapter 20 of the great work "CLR via C#" by Jeffrey Richter. It will definitely answer most of your questions and help understand how .NET framework handles exceptions under the hood, and how use Performance Counter as a mean to assess the impact of the exceptions your code throws.
Using Guard Clauses (as you mention in your question) is not an alternative to exception handling, they are two complimentary concepts. A guard condition such as
if(file exists)
might short circuit the rest of the conditions and yield better performance since your code may not need to test the following conditions i.e.if(user is authorized)
might be resource intensive or time consuming.