下面你会看到一个基准测试。 左键使用返回值,右键使用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版本执行得更好,则向死分支添加更多代码。