我知道以下catch and throw
块是多余的,我很好奇它可以造成什么样的伤害?
编译器可以在发布模式下优化它吗?或者它只会抓住异常并重新抛出它?如果是后一种情况,会导致什么样的性能损失?
try
{
//...
}
catch {
throw;
}
答案 0 :(得分:7)
即使在发布版本中,编译器也不会对此进行优化。
参加以下测试申请:
public class Program {
public static void Main(string[] args) {
try {
CallsThrow();
}
catch(Exception ex) {
Console.WriteLine("Main() caught exception: " + ex.Message);
}
Console.Read();
}
private static void CallsThrow() {
try {
Throw();
}
catch {
throw;
}
}
private static void Throw() {
throw new Exception("Here's my exception.");
}
}
使用ILSpy我们可以查看IL级别的输出二进制文件。我们发现try
中的catch
/ CallsThrow
仍在我们的发布二进制文件中:
.method private hidebysig static
void CallsThrow () cil managed
{
// Method begins at RVA 0x2094
// Code size 11 (0xb)
.maxstack 1
.try
{
IL_0000: call void JunkCSharpConsole.Program::Throw()
IL_0005: leave.s IL_000a
} // end .try
catch [mscorlib]System.Object
{
IL_0007: pop
IL_0008: rethrow
} // end handler
IL_000a: ret
} // end of method Program::CallsThrow
<强>代码:强>
public class Program
{
public static void Main(string[] args) {
const int N = 100000000;
#if DEBUG
const string mode = "Debug";
#else
const string mode = "Release";
#endif
Console.WriteLine("Testing {0} iterations in {1} mode:", N, mode);
// Attempt to JIT / cache
CallsThrowWithTryCatch(false);
CallsThrowWithoutTryCatch(false);
// Test with try/catch+throw
var s1 = Stopwatch.StartNew();
for (int i = 0; i < N; i++ )
CallsThrowWithTryCatch(false);
s1.Stop();
Console.WriteLine(" With try/catch: {0} ms", s1.ElapsedMilliseconds);
// Test without try/catch+throw
var s2 = Stopwatch.StartNew();
for (int i = 0; i < N; i++)
CallsThrowWithoutTryCatch(false);
s2.Stop();
Console.WriteLine(" Without try/catch: {0} ms", s2.ElapsedMilliseconds);
var pct = (s1.ElapsedMilliseconds - s2.ElapsedMilliseconds) / (double)s1.ElapsedMilliseconds * 100.0;
Console.WriteLine("No try/catch faster by {0:.02}%", pct);
// Just show that it works
try {
CallsThrowWithTryCatch(true);
}
catch (Exception ex) {
Console.WriteLine("Main() caught exception: " + ex.Message);
}
// Wait to exit
Console.WriteLine("Press ENTER to exit.");
Console.Read();
}
private static void CallsThrowWithTryCatch(bool doThrow) {
try {
Throw(doThrow);
}
catch {
throw;
}
}
private static void CallsThrowWithoutTryCatch(bool doThrow) {
Throw(doThrow);
}
private static void Throw(bool doThrow) {
if (doThrow)
throw new Exception("Here's my exception.");
}
}
<强>结果:强>
Testing 100000000 iterations in Debug mode:
With try/catch: 1492 ms
Without try/catch: 1474 ms
No try/catch faster by 1.22%
Main() caught exception: Here's my exception.
Press ENTER to exit.
Testing 100000000 iterations in Release mode:
With try/catch: 598 ms
Without try/catch: 458 ms
No try/catch faster by 23.42%
Main() caught exception: Here's my exception.
Press ENTER to exit.
我们可以看到,是的,即使空try
/ catch
, 也会导致性能损失。在Debug版本中,它并不那么重要,但是通过删除try
/ catch
,版本构建显示了23.42%的显着提升。