Pregunta

Mi aplicación lee un archivo de Excel usando VSTO y agrega los datos leídos a un StringDictionary.Agrega solo datos que son números con unos pocos dígitos (1000 1000,2 1000,34; la coma es un delimitador en los estándares rusos).

¿Qué es mejor comprobar si la cadena actual es un número apropiado?

object data, string key; // data had read

try
{
  Convert.ToDouble(regionData, CultureInfo.CurrentCulture);
  dic.Add(key, regionData.ToString());
}
catch (InvalidCastException)
{
  // is not a number
}

o

double d;
string str = data.ToString();
if (Double.TryParse(str, out d)) // if done, then is a number
{
  dic.Add(key, str);
}

tengo que usar StringDictionary en lugar de Dictionary<string, double> debido a los siguientes problemas con el algoritmo de análisis.

Mis preguntas:¿Qué camino es más rápido?¿Cuál es más seguro?

¿Y es mejor llamar? Convert.ToDouble(object) o Convert.ToDouble(string) ?

¿Fue útil?

Solución

Hice una prueba rápida no científica en el modo Lanzamiento.Usé dos entradas:"2.34523" y "badinput" en ambos métodos y se iteraron 1.000.000 de veces.

Entrada válida:

Double.TryParse = 646ms
Convert.ToDouble = 662 ms

No muy diferente, como se esperaba.Para todos los efectos, para entradas válidas, estos son los mismos.

Entrada inválida:

Double.TryParse = 612ms
Convert.ToDouble = ..

Bien..estuvo funcionando durante mucho tiempo.Volví a ejecutar todo usando 1000 iteraciones y Convert.ToDouble con mala entrada tomó 8,3 segundos.En promedio, tomaría más de 2 horas.No me importa cuán básica sea la prueba, en el caso de entrada no válida, Convert.ToDoubleEl aumento de excepciones arruinará su desempeño.

Entonces, aquí hay otro voto a favor TryParse con algunos números que lo respaldan.

Otros consejos

Para empezar, me gustaría usar en lugar de double.Parse Convert.ToDouble en el primer lugar.

En cuanto a si se debe utilizar o Parse TryParse: ¿se puede proceder si hay malos datos de entrada, o es que una condición realmente excepcional? Si es excepcional, utilizar Parse y se deja volar si la entrada es mala. Si se espera y se puede manejar limpiamente, utilice TryParse.

Las directrices de diseño de .NET Framework recomiendan el uso de los métodos tratan. Evitar excepciones es generalmente una buena idea.

Convert.ToDouble(object) hará ((IConvertible) object).ToDouble(null);

¿Qué va a llamar Convert.ToDouble(string, null)

Así que es más rápido que llamar a la versión de cadena.

Sin embargo, la versión de cadena sólo hace esto:

if (value == null)
{
    return 0.0;
}
return double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);

Así que es más rápido para hacer el double.Parse directamente.

Si no se van a manejar la excepción ir con TryParse. TryParse es más rápido, ya que no tiene que lidiar con toda la traza de la pila es una excepción.

Yo por lo general trato de evitar la clase Convert (que significa: Yo no lo uso) porque me resulta muy confuso: el código da muy pocas pistas sobre qué es exactamente lo que sucede aquí desde Convert permite una gran cantidad de semánticamente muy diferentes a las conversiones ocurrir con el mismo código. Esto hace que sea difícil de controlar para el programador de qué es exactamente lo que está sucediendo.

Mi consejo, por lo tanto, nunca debe utilizar esta clase. En realidad no es necesario o bien (excepto para el formato binario de un número, ya que el método normal de clases ToString número no ofrece un método apropiado para hacer esto).

A menos que esté 100% seguro de sus entradas, lo que no suele ser el caso, se debe utilizar Double.TryParse.

Convert.ToDouble will throw an exception on non-numbers
Double.Parse will throw an exception on non-numbers or null
Double.TryParse will return false or 0 on any of the above without generating an exception.

La velocidad del análisis sintáctico se vuelve secundario cuando se lanza una excepción, ya que no es mucho más lento que una excepción.

Un montón de odio de la clase Convert aquí ... sólo para equilibrar un poco, hay una ventaja para convertir - si se le entregó un objeto,

Convert.ToDouble(o);

simplemente puede devolver el valor fácilmente si o ya es un doble (o un int o cualquier cosa fácilmente moldeable).

El uso de Double.Parse o Double.TryParse es grande si ya lo tienes en una cadena, pero

Double.Parse(o.ToString());

tiene que ir make de la cadena a analizar primero y dependiendo de su entrada que podría ser más caro.

Double.TryParse OMI.

Es más fácil para que usted resuelva, usted sabrá exactamente dónde se produjo el error.

A continuación, se puede tratar con él cómo le parezca si devuelve falso (es decir, no pudo convertir).

Siempre he preferido el uso de los métodos TryParse() porque va a escupir hacia atrás éxito o el fracaso de convertir sin tener que preocuparse acerca de las excepciones.

En lo personal, creo que el método TryParse más fácil de leer, que uno que realmente va a desea utilizar depende de su caso de uso: si los errores se pueden manejar los errores a nivel local y se espera alcanzar un bool de TryParse es bueno, de lo contrario puede ser que desee dejar que las excepciones vuelan.

Yo esperaría que el TryParse para ser más rápido también, ya que evita la sobrecarga de gestión de excepciones. Pero el uso de una herramienta de referencia, como Jon Skeet MINIBENCH para comparar las distintas posibilidades.

Esta es una vieja pregunta interesante. Estoy agregando una respuesta porque nadie se dio cuenta un par de cosas con la pregunta original.

¿Qué es más rápido: Convert.ToDouble o Double.TryParse? ¿Qué es más seguro:? Convert.ToDouble o Double.TryParse

Voy a responder a estas dos preguntas (Voy a actualizar la respuesta más adelante), en detalle, pero primero:

Por razones de seguridad, la cosa todos programador perdido en esta cuestión es la línea (el énfasis es mío):

  

Se añade únicos datos que son números con unos pocos dígitos (1000 1000,2 1000,34 - coma es un delimitador en los estándares rusos ).

Seguido por este ejemplo de código:

Convert.ToDouble(regionData, CultureInfo.CurrentCulture);

Lo que es interesante aquí es que si las hojas de cálculo están en formato de número de Rusia, pero Excel no ha escrito correctamente los campos de celda, ¿cuál es la interpretación correcta de los valores que vienen de Excel?

Aquí hay otra cosa interesante de los dos ejemplos, en relación con la velocidad:

catch (InvalidCastException)
{
    // is not a number
}

Esto es probable que va a generar MSIL que tiene este aspecto:

catch [mscorlib]System.InvalidCastException 
{
  IL_0023:  stloc.0
  IL_0024:  nop
  IL_0025:  ldloc.0
  IL_0026:  nop
  IL_002b:  nop
  IL_002c:  nop
  IL_002d:  leave.s    IL_002f
}  // end handler
IL_002f: nop
IL_0030: return

En este sentido, probablemente podemos comparar el número total de instrucciones MSIL llevadas a cabo por cada programa -. Lo veremos más adelante, ya que actualizar este post

Creo código debe ser correcta, clara y rápida ... En ese orden!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top