Rob*_*son 67
Jon Skeet 于2006年1月在.NET中编写了Exceptions和Performance
哪个更新了Exceptions和Performance Redux(感谢@Gulzar)
Rico Mariani在.NET异常的真实成本中所说的 - 解决方案
另请参考:Krzysztof Cwalina - 设计指南更新:异常投掷
Hel*_*ein 17
在阅读了异常在性能方面代价高昂之后,我将一个简单的测量程序整合在一起,与Jon Skeet多年前发布的程序非常相似.我在这提到这里主要是为了提供更新的数字.
程序花费了29914毫秒来处理一百万个异常,相当于每毫秒33个异常.这足够快,使异常成为大多数情况下返回代码的可行替代方案.
但请注意,使用返回代码而不是异常,同一程序运行时间不到一毫秒,这意味着异常至少比返回代码慢30,000倍.正如Rico Mariani强调的那样,这些数字也是最小数字.在实践中,抛出和捕获异常将花费更多时间.
在具有英特尔酷睿2双核T8100 @ 2,1 GHz的笔记本电脑上测试,发布版本中的.NET 4.0 不能在调试器下运行(这会使速度变慢).
这是我的测试代码:
static void Main(string[] args)
{
int iterations = 1000000;
Console.WriteLine("Starting " + iterations.ToString() + " iterations...\n");
var stopwatch = new Stopwatch();
// Test exceptions
stopwatch.Reset();
stopwatch.Start();
for (int i = 1; i <= iterations; i++)
{
try
{
TestExceptions();
}
catch (Exception)
{
// Do nothing
}
}
stopwatch.Stop();
Console.WriteLine("Exceptions: " + stopwatch.ElapsedMilliseconds.ToString() + " ms");
// Test return codes
stopwatch.Reset();
stopwatch.Start();
int retcode;
for (int i = 1; i <= iterations; i++)
{
retcode = TestReturnCodes();
if (retcode == 1)
{
// Do nothing
}
}
stopwatch.Stop();
Console.WriteLine("Return codes: " + stopwatch.ElapsedMilliseconds.ToString() + " ms");
Console.WriteLine("\nFinished.");
Console.ReadKey();
}
static void TestExceptions()
{
throw new Exception("Failed");
}
static int TestReturnCodes()
{
return 1;
}
Run Code Online (Sandbox Code Playgroud)
Col*_*ett 16
我想我在营地,如果异常影响应用程序的性能,然后你扔WAY太多了.例外情况应该是特殊条件,而不是常规错误处理.
也就是说,我对如何处理异常的回忆基本上是在堆栈中找到一个与抛出的异常类型相匹配的catch语句.因此,性能将受到影响,因为您从捕获的深度以及您拥有的捕获语句数量.
就我而言,例外非常昂贵。我改写了这个:
public BlockTemplate this[int x,int y, int z]
{
get
{
try
{
return Data.BlockTemplate[World[Center.X + x, Center.Y + y, Center.Z + z]];
}
catch(IndexOutOfRangeException e)
{
return Data.BlockTemplate[BlockType.Air];
}
}
}
Run Code Online (Sandbox Code Playgroud)
进入这个:
public BlockTemplate this[int x,int y, int z]
{
get
{
int ix = Center.X + x;
int iy = Center.Y + y;
int iz = Center.Z + z;
if (ix < 0 || ix >= World.GetLength(0)
|| iy < 0 || iy >= World.GetLength(1)
|| iz < 0 || iz >= World.GetLength(2))
return Data.BlockTemplate[BlockType.Air];
return Data.BlockTemplate[World[ix, iy, iz]];
}
}
Run Code Online (Sandbox Code Playgroud)
我注意到速度增加了大约 30 秒。该函数在启动时至少被调用 32,000 次。代码的意图不是很清楚,但节省的成本是巨大的。
我自己进行了测量,以了解异常影响的严重程度。我没有尝试测量抛出/捕获异常的绝对时间。我最感兴趣的是,如果在每次传递中抛出异常,循环会变慢多少。测量代码如下所示:
for(; ; ) {
iValue = Level1(iValue);
lCounter += 1;
if(DateTime.Now >= sFinish)
break;
}
Run Code Online (Sandbox Code Playgroud)
与
for(; ; ) {
try {
iValue = Level3Throw(iValue);
}
catch(InvalidOperationException) {
iValue += 3;
}
lCounter += 1;
if(DateTime.Now >= sFinish)
break;
}
Run Code Online (Sandbox Code Playgroud)
相差20倍。第二个片段慢了 20 倍。
| 归档时间: |
|
| 查看次数: |
28830 次 |
| 最近记录: |