C#/ .NET异常性能?

时间:2017-01-11 21:11:12

标签: c# .net performance exception

下面你会看到一个基准测试。 左键使用返回值,右键使用try / catch。 这条线

if(i < 0) throw new Exception("xxxx");

让我头疼。 i 永远不会<0,因此永远不会抛出异常。但是为什么DoTry比使用返回值慢得多。有趣的是,如果我省略“xxxx”并写Exception()DoTry()Do()快。但是带有throw的分支永远不会执行,那么为什么如果将字符串传递给Exception会产生性能差异呢?

XAML

<Window x:Class="ExceptionTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ExceptionTest"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" TextOptions.TextFormattingMode="Display">
    <Grid>
    <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="102,60,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/>
    <Button x:Name="button1" Content="Button" HorizontalAlignment="Left" Margin="287,60,0,0" VerticalAlignment="Top" Width="75" Click="button1_Click"/>

  </Grid>
</Window>

C#

using System;
using System.Diagnostics;
using System.Windows;

namespace ExceptionTest {
  public partial class MainWindow : Window {
    public MainWindow() {
      InitializeComponent();
    }

    long ii = 10000000;

    private void button_Click(object sender, RoutedEventArgs e) {
      Stopwatch sw = new Stopwatch();
      sw.Start();
      for(long i = ii; i > 0; i--) {
        for(int j = 100; j > 0; j--) {
          bool r = Do();
        }
      }
      sw.Stop();
      Title = sw.ElapsedMilliseconds.ToString();
    }

    private void button1_Click(object sender, RoutedEventArgs e) {
      Stopwatch sw = new Stopwatch();
      sw.Start();
      for(long i = ii; i > 0; i--) {
        try {
          for(int j = 100; j > 0; j--) {
            DoTry();
          }
        } catch(Exception ex) {
        }
      }
      sw.Stop();
      Title = sw.ElapsedMilliseconds.ToString();
    }

    void DoTry() {
      int i = 1;
      i++;
      if(i < 0) throw new Exception("xxxx");
    }

    bool Do() {
      int i = 1;
      i++;
      if(i < 0) return false;
      return true;
    }
  }
}

答案:正如Sefe所说,它看起来像是内联。如果Do函数导致Try版本执行得更好,则向死分支添加更多代码。

0 个答案:

没有答案