tipos - try catch c# windows form
Rendimiento de anĂ¡lisis(si, TryParse, Try-Catch) (5)
Sé mucho sobre las diferentes maneras de manejar el análisis de texto para obtener información. Para analizar enteros, por ejemplo, qué tipo de rendimiento se puede esperar. Me pregunto si alguien sabe de alguna buena estadística sobre esto. Estoy buscando algunos números reales de alguien que ha probado esto.
¿Cuál de estos ofrece el mejor rendimiento en qué situaciones?
Parse(...) // Crash if the case is extremely rare .0001%
If (SomethingIsValid) // Check the value before parsing
Parse(...)
TryParse(...) // Using TryParse
try
{
Parse(...)
}
catch
{
// Catch any thrown exceptions
}
Aquí hay otro capítulo que también ha perfilado las diferencias de rendimiento , y lo hace con algunos tipos de datos diferentes para ver cuánto (si es que lo hacen) afectan intrínsecamente el rendimiento: int, bool y DateTime.
Aunque no he perfilado personalmente las diferentes formas, este muchacho tiene:
Siempre use T.TryParse (string str, out T value) . Lanzar excepciones es costoso y debe evitarse si puede manejar la situación a priori . El uso de un bloque try-catch para "guardar" el rendimiento (debido a que su velocidad de datos inválida es baja) es un abuso del manejo de excepciones a expensas de la facilidad de mantenimiento y las buenas prácticas de codificación. Siga las prácticas de desarrollo de ingeniería de software, escriba sus casos de prueba, ejecute su aplicación, luego compare y optimice.
"Deberíamos olvidarnos de las pequeñas eficiencias, digamos el 97% del tiempo: la optimización prematura es la raíz de todo mal . Sin embargo, no deberíamos dejar pasar nuestras oportunidades en ese crucial 3%" -Donald Knuth
Por lo tanto, asigna, arbitrariamente como en créditos de carbono, que el rendimiento de try-catch es peor y que el rendimiento de TryParse es mejor . Solo después de que hayamos ejecutado nuestra aplicación y determinado que tenemos algún tipo de desaceleración, el análisis sintáctico de cadenas de caracteres consideraría siquiera usar algo que no sea TryParse.
(Editar: dado que parece que el cuestionario quería que los datos de tiempo fueran buenos, aquí están los datos de tiempo solicitados)
Tiempos para varias tasas de fallas en 10.000 entradas del usuario (para los incrédulos):
Failure Rate Try-Catch TryParse Slowdown
0% 00:00:00.0131758 00:00:00.0120421 0.1
10% 00:00:00.1540251 00:00:00.0087699 16.6
20% 00:00:00.2833266 00:00:00.0105229 25.9
30% 00:00:00.4462866 00:00:00.0091487 47.8
40% 00:00:00.6951060 00:00:00.0108980 62.8
50% 00:00:00.7567745 00:00:00.0087065 85.9
60% 00:00:00.7090449 00:00:00.0083365 84.1
70% 00:00:00.8179365 00:00:00.0088809 91.1
80% 00:00:00.9468898 00:00:00.0088562 105.9
90% 00:00:01.0411393 00:00:00.0081040 127.5
100% 00:00:01.1488157 00:00:00.0078877 144.6
/// <param name="errorRate">Rate of errors in user input</param>
/// <returns>Total time taken</returns>
public static TimeSpan TimeTryCatch(double errorRate, int seed, int count)
{
Stopwatch stopwatch = new Stopwatch();
Random random = new Random(seed);
string bad_prefix = @"X";
stopwatch.Start();
for(int ii = 0; ii < count; ++ii)
{
string input = random.Next().ToString();
if (random.NextDouble() < errorRate)
{
input = bad_prefix + input;
}
int value = 0;
try
{
value = Int32.Parse(input);
}
catch(FormatException)
{
value = -1; // we would do something here with a logger perhaps
}
}
stopwatch.Stop();
return stopwatch.Elapsed;
}
/// <param name="errorRate">Rate of errors in user input</param>
/// <returns>Total time taken</returns>
public static TimeSpan TimeTryParse(double errorRate, int seed, int count)
{
Stopwatch stopwatch = new Stopwatch();
Random random = new Random(seed);
string bad_prefix = @"X";
stopwatch.Start();
for(int ii = 0; ii < count; ++ii)
{
string input = random.Next().ToString();
if (random.NextDouble() < errorRate)
{
input = bad_prefix + input;
}
int value = 0;
if (!Int32.TryParse(input, out value))
{
value = -1; // we would do something here with a logger perhaps
}
}
stopwatch.Stop();
return stopwatch.Elapsed;
}
public static void TimeStringParse()
{
double errorRate = 0.1; // 10% of the time our users mess up
int count = 10000; // 10000 entries by a user
TimeSpan trycatch = TimeTryCatch(errorRate, 1, count);
TimeSpan tryparse = TimeTryParse(errorRate, 1, count);
Console.WriteLine("trycatch: {0}", trycatch);
Console.WriteLine("tryparse: {0}", tryparse);
}
Try-Catch siempre será el más lento. TryParse será más rápido.
El IF y TryParse son iguales.
Option 1: Will throw an exception on bad data.
Option 2: SomethingIsValid() could be quite expensive - particularly if you are pre-checking a string for Integer parsability.
Option 3: I like this. You need a null check afterwards, but it''s pretty cheap.
Option 4 is definitely the worst.
El manejo de excepciones es comparativamente caro, así que evítelo si puede.
En particular, se esperan entradas malas, no excepcionales, por lo que no debe usarlas para esta situación.
(Aunque, antes de TryParse, puede haber sido la mejor opción).