try tipos que propiedades programacion las existen excepciones errores ejemplos definicion como catch capturar c# exception

tipos - ¿Qué tan costosas son las excepciones en C#?



try catch c# messagebox (7)

Después de leer que las excepciones son costosas en términos de rendimiento, armé un programa de medición simple, muy similar al que publicó Jon Skeet hace años . Menciono esto aquí principalmente para proporcionar números actualizados.

Tomó el programa por debajo de 29914 milisegundos para procesar un millón de excepciones, lo que equivale a 33 excepciones por milisegundo . Eso es lo suficientemente rápido como para hacer que las excepciones sean una alternativa viable a los códigos de retorno para la mayoría de las situaciones.

Sin embargo, tenga en cuenta que con los códigos de retorno en lugar de excepciones, el mismo programa ejecuta menos de un milisegundo, lo que significa que las excepciones son al menos 30,000 veces más lentas que los códigos de retorno . Como subrayó Rico Mariani, estos números también son números mínimos. En la práctica, lanzar y atrapar una excepción tomará más tiempo.

Medido en una computadora portátil con Intel Core 2 Duo T8100 a 2,1 GHz con .NET 4.0 en la versión de compilación no se ejecuta bajo el depurador (lo que lo haría mucho más lento).

Este es mi código de prueba:

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; }

¿Qué tan costosas son las excepciones en C #? Parece que no son increíblemente caros, siempre y cuando la pila no sea profunda; sin embargo, he leído informes contradictorios.

¿Hay algún informe definitivo que no haya sido refutado?


El rendimiento alcanzado con excepciones parece estar en el punto de generar el objeto de excepción (aunque demasiado pequeño para causar preocupaciones el 90% del tiempo). Por lo tanto, la recomendación es perfilar su código: si las excepciones están causando un impacto en el rendimiento, escriba un nuevo método de alto rendimiento que no use excepciones. (Un ejemplo que viene a la mente sería (TryParse introdujo para superar problemas de rendimiento con Parse que usa excepciones)

Sin embargo, en la mayoría de los casos, las excepciones no causan resultados de rendimiento significativos en la mayoría de las situaciones, por lo que la Guía de diseño de MS debe informar las fallas arrojando excepciones.


En mi caso, las excepciones fueron muy costosas. Reescribí esto:

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]; } } }

Dentro de esto:

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]]; } }

Y notó un buen aumento de velocidad de aproximadamente 30 segundos. Esta función se llama al menos 32K veces al inicio. El código no es tan claro como cuál es la intención, pero el ahorro de costos fue enorme.


Hice mis propias mediciones para descubrir cuán grave es la implicación de las excepciones. No intenté medir el tiempo absoluto para arrojar / atrapar excepción. Lo que más me interesó fue saber cuánto más lento se volverá un bucle si se lanza una excepción en cada pase. El código de medición se ve así

for(; ; ) { iValue = Level1(iValue); lCounter += 1; if(DateTime.Now >= sFinish) break; }

vs

for(; ; ) { try { iValue = Level3Throw(iValue); } catch(InvalidOperationException) { iValue += 3; } lCounter += 1; if(DateTime.Now >= sFinish) break; }

La diferencia es 20 veces. El segundo fragmento es 20 veces más lento.



Los objetos de excepción de Barebones en C # son bastante livianos; por lo general, la capacidad de encapsular una InnerException hace pesado cuando el árbol de objetos se vuelve demasiado profundo.

En cuanto a un informe definitivo, no conozco ninguno, aunque un perfil de dotTrace superficial (o cualquier otro generador de perfiles) para el consumo de memoria y la velocidad será bastante fácil de hacer.


Supongo que estoy en el campo de que si el rendimiento de las excepciones afecta tu aplicación, estás lanzando MUCHOS de ellos. Las excepciones deben ser para condiciones excepcionales, no como manejo de errores de rutina.

Dicho esto, mi recuerdo de cómo se manejan las excepciones es, esencialmente, subir la pila encontrando una declaración catch que coincida con el tipo de excepción lanzada. Por lo tanto, el rendimiento se verá más afectado por la profundidad de la captura y la cantidad de declaraciones de captura que tenga.