2011-05-11 31 views
8

considera la siguiente función:¿Existe alguna forma mejor de manejar una excepción de conversión?

public enum Operator 
{ 
    EQUAL = 1, 
    GREATER_THAN = 2 
} 

public class checkString 
{ 
    public static bool isValid(string inputString, string checkString, Operator operation) 
    { 
     switch (operation) 
     { 
      case Operator.EQUAL: 
       if (inputString == checkString) 
        return true; 

       break; 

      case Operator.GREATER_THAN: 

       // Numeric check for greater than 
       try 
       { 
        double inputDouble, checkDouble; 

        inputDouble = Convert.ToDouble(inputString); 
        checkDouble = Convert.ToDouble(checkString); 

        if (inputDouble > checkDouble) 
         return true; 
       } 
       catch (Exception) 
       { } 

       // Date check for greater than 
       try 
       { 
        DateTime inputDate, checkDate; 

        inputDate = DateTime.Parse(inputString); 
        checkDate = DateTime.Parse(inputString); 

        if (inputDate. > checkDate) 
         return true; 
       } 
       catch (Exception) 
       { } 

       break; 
     } 
     return false; 
    } 
} 

Parámetros

  • inputString: Lo que queremos evaluar
  • checkString: Los criterios (valor) que la entrada debe evaluar contra
  • Operador: Enum para la operación que queremos realizar

Otras informaciones

  • Cada línea en un archivo se evalúa en contra de este método para devolver si una condición se ha cumplido
  • El proceso de evaluación de los registros de la línea de cheques de archivos por línea, en un caso que es igual a la condición. También puede verificar que la misma línea también sea mayor que la condición. Una vez que los cheques se hacen, se mueve al siguiente registro
  • No se enganchan no hay detectores de eventos adicionales hasta que no sea lo que sea por defecto están en su lugar, no estoy enviando datos adicionales para depurar o registros de seguimiento

Problema

Lo que la gente va a evaluar es desconocido para mí en cualquier momento de este proceso, pero necesito poder verificar que 'algo' (independientemente de qué) sea igual a, mayor o menor que otra cosa. Claro que verifico otras cosas pero simplifiqué esta función en gran medida.

Dicho esto, usar EQUAL o NOT_EQUAL funciona tan rápido como sea posible, procesando registros en un archivo muy grande contra dichos criterios de forma bastante rápida y eficiente. Una vez que agregué la lógica GREATER_THAN, es lenta ... hasta el punto en que lleva unos minutos procesar 20 meg de archivos que solían tardar medio minuto en llegar.

De lo que puedo decir:

  • se lanzan excepciones por todo el lugar. No hay garantía de que un campo sea numérico o de tipo de fecha. Por lo que debe tratar de echar a estos tipos de datos para intentar evaluar la condición
  • Cuando se producen excepciones, la consola obtiene de salida donde no he instruido que lo haga, su tipo de automatizado

Sí Tengo una falta de experiencia en esta área y estoy buscando aprender más sobre el manejo de excepciones y lo que realmente sucede detrás de escena porque cuando el otro 80% de los registros no son numéricos, eso es una gran cantidad de excepciones en un registro de 20 megas, 80 mil archivo.

¿Hay una mejor manera de manejar el molde para aumentar la eficiencia? He visto double.Parse/TryParse y puedo dirigir el reparto al frente, pero no estoy seguro de cuáles son los beneficios más.

Respuesta

8

Puede usar TryParse() en esos tipos de datos. Las excepciones son desordenadas y costosas. TryParse devolverá verdadero/falso si funcionó o no mientras NO lanza una excepción. Entonces puede verificar los resultados de la llamada. Mucho más eficiente que las excepciones.

Convert.ToDouble() y Double.Parse() arrojarán excepciones.

prueba este código. No es el mejor, pero es mejor que lo que ahora ha teniendo en cuenta que no sabe lo que podría ser del tipo:

public static bool isValid(string inputString, string checkString, Operator operation)  
     {   
      double dblTmp1; 
      double dblTmp2; 

      if (Double.TryParse(inputString, out dblTmp1) && double.TryParse(checkString, out dblTmp2)) 
      { 
       return Compare<Double>(dblTmp1, dblTmp1, operation); 
      } 

      DateTime dtTmp1; 
      DateTime dtTmp2; 
      if (DateTime.TryParse(inputString, out dtTmp1) && DateTime.TryParse(checkString, out dtTmp2)) 
      { 
       return Compare<DateTime>(dtTmp1, dtTmp2, operation); 
      } 

      throw new InvalidOperationException("Unknown type"); 

     } 

     public static bool Compare<T>(T obj1, T obj2, Operator operation) where T : IComparable  
     { 
      switch (operation) 
      { 
       case Operator.EQUAL: 
        { 
         return obj1.Equals(obj2); 
        } 
       case Operator.GREATER_THAN: 
        { 
         return obj1.CompareTo(obj2) > 0; 
        } 
       default: 
        { 
         throw new InvalidOperationException("Unknown operation"); 
        } 
      } 
     } 
+0

Vaya, es un uso extremadamente elegante de los genéricos ... Estoy impresionado. Es agradable ver la comparación abstraída de la conversión – Mohgeroth

+0

¡Impresionante! Es tan impresionante. – Justin

+1

El tiempo que tardó en hacer un único archivo, puede procesar más de 120 archivos (de 5 a 30 megas por pieza) ahora en comparación con más de 200 reglas evaluadas en cada línea. La pieza extra que hace que esta sea mi respuesta favorita es el método genérico. Para mí es una maravillosa vista de dónde pertenecen los métodos genéricos ... no es mi área más fuerte y aunque entiendo cómo funcionan, es difícil ver el contexto de dónde encajan cuando no estás bien versado. Gracias por este conocimiento, una respuesta bien ganada :) – Mohgeroth

2

Tenga en cuenta que el uso de excepciones ralentiza su programa, porque detrás de las escenas el tiempo de ejecución es la creación de una pila de excepción con el fin de ser capaz de relajarse esto en caso de una excepción es arrojado. Esta pila se mantiene independientemente de si su programa lanza o no, y esa sobrecarga es lo que más le ralentiza.

+0

Al menos mi mente estaba en el lugar correcto, ¡gracias por los detalles técnicos! Eso es una buena parte de lo que estoy buscando aprender mientras resuelvo mi problema :) – Mohgeroth

0

Las otras respuestas son probablemente la mejor solución en este caso, pero en el caso general puede mejorar su solución atrapando la excepción específica, que es probablemente NumberFormatException o ClassCastException. Capturar Exception puede causar todo tipo de problemas molestos y difíciles de rastrear (ya que no está registrando la excepción).

Cuestiones relacionadas