在异常处理中,try部分的代码量越大,对性能的影响有多大?

In exception handling, how much does the impact on performance grow with the quantity of code in the try section?

我将在 C# 中给出一个示例。

以下两个清单实现了相同的目的。案例 2 的样式肯定比案例 1 更好,因为 try 部分隔离了抛出异常的行。

我很想知道性能是否有所不同,如果有,它如何随着 try 部分中包含的代码量进行扩展?

最后,为什么会这样?

案例一:

        try
        {
            BinaryFormatter bf = new BinaryFormatter();
            FileStream file = File.Open(Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
            data = (PlayerData)bf.Deserialize(file);
            file.Close();
        } catch (System.Runtime.Serialization.SerializationException e)
        {
            ...
        }

案例二:

        BinaryFormatter bf = new BinaryFormatter();
        FileStream file = File.Open(Application.persistentDataPath + "/playerInfo.dat", FileMode.Open);
        try
        {
            data = (PlayerData)bf.Deserialize(file);
        } catch (System.Runtime.Serialization.SerializationException e)
        {

        }
        file.Close();

try 块中的代码量不会影响性能。事实上,try 块的存在根本不会产生什么影响。 .NET 中异常的代价是在它们被抛出时出现,并且运行时必须执行堆栈展开。

从您关心的调用中仅捕获您关心的异常集。

在您的情况 2 中,您正在消除该异常。那是你想要的吗?如果您只想确保文件已关闭,请使用不带 catch 语句的 try / finally。

参见:

  • Why are try blocks expensive?
  • How expensive are exceptions in C#?
  • How slow are .NET exceptions?

如果没有异常发生,try的性能开销很小。 但在情况 2 中,你总是关闭文件,我认为它是更好的解决方案。如果情况 1 发生,一些异常文件也会被关闭,但后者会在垃圾收集器释放您的 FileStream 对象时关闭。

正如@jonathon所说,代码量对性能没有影响,异常的发生对性能有影响。但请注意将容易出现异常的代码放在 try 块中,因为如果您不处理异常,CLR 将控制您的应用程序,这绝对是糟糕且昂贵的。因为调用堆栈展开直到找到合适的捕获,其中没有处理块(捕获块)。