parse - object to double c#
Double.TryParse o Convert.ToDouble-¿Qué es más rápido y más seguro? (10)
A menos que esté 100% seguro de sus entradas, lo que rara vez es el caso, debe usar 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 se vuelve secundaria cuando lanza una excepción porque no hay mucho más lento que una excepción.
Mi aplicación lee un archivo Excel usando VSTO y agrega los datos leídos a un StringDictionary
. Agrega solo datos que son números con algunos dígitos (1000 1000,2 1000,34 - la coma es un delimitador en los estándares rusos).
¿Qué es mejor verificar 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
lugar de Dictionary<string, double>
debido a los siguientes problemas del algoritmo de análisis.
Mis preguntas: ¿Qué camino es más rápido? ¿Cuál es más seguro?
¿Y es mejor llamar a Convert.ToDouble(object)
o Convert.ToDouble(string)
?
Aquí hay mucho odio por la clase Convert ... Solo para equilibrar un poco, hay una ventaja para Convert: si le entregan un objeto,
Convert.ToDouble(o);
puede simplemente devolver el valor fácilmente si o ya es un Double (o un int o cualquier elemento que se pueda convertir fácilmente).
Usar Double.Parse o Double.TryParse es genial si ya lo tienes en una cadena, pero
Double.Parse(o.ToString());
tiene que hacer que la cadena sea analizada primero y, dependiendo de su entrada, puede ser más costosa.
Double.TryParse IMO.
Es más fácil de manejar, sabrá exactamente dónde ocurrió el error.
Entonces puede manejarlo como le parezca mejor si devuelve falso (es decir, no se pudo convertir).
Generalmente trato de evitar la clase Convert
(es decir, no la uso) porque la encuentro muy confusa: el código da muy pocas pistas sobre qué sucede exactamente aquí, ya que Convert
permite que ocurran muchas conversiones semánticamente muy diferentes con el mismo código Esto hace que sea difícil controlar para el programador lo que está sucediendo exactamente.
Mi consejo, por lo tanto, es nunca usar esta clase. Tampoco es realmente necesario (excepto para el formato binario de un número, porque el método normal de ToString
de las clases numéricas no ofrece un método apropiado para hacerlo).
Hice una prueba rápida no científica en el modo de lanzamiento. Usé dos entradas: "2.34523" y "badinput" en ambos métodos e iteración 1,000,000 de veces.
Entrada válida:
Double.TryParse = 646ms
Convert.ToDouble = 662 ms
No es muy diferente, como se esperaba. Para todos los efectos, para una entrada válida, estos son los mismos.
Entrada inválida:
Double.TryParse = 612ms
Convert.ToDouble = ..
Bueno ... estuvo funcionando durante mucho tiempo. Volví a usar todo el proceso con 1,000 iteraciones y Convert.ToDouble
con una mala entrada me llevó 8,3 segundos. Promediando, tomaría más de 2 horas. No me importa qué tan básica es la prueba, en el caso de entrada no válida, la excepción de Convert.ToDouble
arruinará su rendimiento.
Entonces, aquí hay otra votación para TryParse
con algunos números para respaldarlo.
Las directrices de diseño de .NET Framework recomiendan utilizar los métodos de prueba. Evitar excepciones suele ser una buena idea.
Convert.ToDouble(object)
lo hará ((IConvertible) object).ToDouble(null);
Que llamará Convert.ToDouble(string, null)
Entonces, es más rápido llamar a la versión de cadena.
Sin embargo, la versión de cadena simplemente hace esto:
if (value == null)
{
return 0.0;
}
return double.Parse(value, NumberStyles.Float | NumberStyles.AllowThousands, provider);
Por lo tanto, es más rápido hacer el double.Parse
. double.Parse
directamente.
Para empezar, usaría double.Parse
lugar de Convert.ToDouble
en primer lugar.
En cuanto a si debe usar Parse
o TryParse
: ¿puede continuar si hay datos de entrada incorrectos, o es realmente una condición excepcional? Si es excepcional, use Parse
y déjelo explotar si la entrada es mala. Si se espera y se puede manejar limpiamente, use TryParse
.
Personalmente, encuentro que el método TryParse
es más fácil de leer, el que realmente querrás usar depende de tu caso de uso: si los errores se pueden manejar localmente, estás esperando errores y un bool de TryParse
es bueno, de lo contrario es posible que desees solo deja volar las excepciones.
Esperaría que el TryParse
sea más rápido también, ya que evita la sobrecarga del manejo de excepciones. Pero use una herramienta de referencia, como MiniBench de Jon Skeet para comparar las diversas posibilidades.
Si no va a manejar la excepción, vaya con TryParse. TryParse es más rápido porque no tiene que ocuparse de todo el trazado de la pila de excepción.
Siempre he preferido utilizar los métodos TryParse()
porque va a escupir el éxito o el fracaso al convertir sin tener que preocuparse por las excepciones.