81 votes

Double.TryParse ou Convert.ToDouble - lequel est le plus rapide et le plus sûr ?

Mon application lit un fichier Excel à l'aide de VSTO et ajoute les données lues à un fichier de données. StringDictionary . Il ajoute uniquement les données qui sont des nombres à quelques chiffres (1000 1000,2 1000,34 - la virgule est un délimiteur dans les normes russes).

Quel est le meilleur moyen de vérifier si la chaîne actuelle est un nombre approprié ?

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

Je dois utiliser StringDictionary au lieu de Dictionary<string, double> en raison des problèmes suivants liés à l'algorithme d'analyse syntaxique.

Mes questions : Quel est le chemin le plus rapide ? Lequel est le plus sûr ?

Et est-il préférable d'appeler Convert.ToDouble(object) o Convert.ToDouble(string) ?

0 votes

Pour info, double.TryParse est la même chose que try { result = double.Parse(s) ; return true ; } catch { return false ; }. Convert est essentiellement une enveloppe pour les deux avec un tas de surcharges. La façon dont vous le faites ne fait aucune différence. Mais comme Jon l'a souligné, pensez à la manière de gérer les entrées erronées.

12 votes

Double.TryParse n'est pas la même chose que double.Parse enveloppé dans un try..catch. La sémantique est la même, mais le chemin de code est différent. TryParse vérifie d'abord que la chaîne de caractères est un nombre en utilisant une fonction interne Number.TryStringToNumber, alors que Parse suppose qu'il s'agit déjà d'un nombre/double.

134voto

Szymon Rozga Points 11277

J'ai fait un rapide test non scientifique en mode Release. J'ai utilisé deux entrées : "2.34523" et "badinput" dans les deux méthodes et j'ai itéré 1.000.000 de fois.

Entrée valide :

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

Pas beaucoup de différence, comme prévu. À toutes fins utiles, pour une entrée valide, ce sont les mêmes.

Entrée invalide :

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

Eh bien ça a fonctionné pendant un long moment. J'ai réexécuté l'ensemble en utilisant 1 000 itérations et Convert.ToDouble avec une mauvaise entrée a pris 8,3 secondes. En faisant la moyenne, cela prendrait plus de 2 heures. Je me fiche de savoir si le test est basique, dans le cas d'une entrée invalide, Convert.ToDouble La levée d'exceptions de la part de l'entreprise ruinera vos performances.

Donc, voici un autre vote pour TryParse avec des chiffres à l'appui.

4 votes

En plus des choses mentionnées ci-dessus, je viens de découvrir que Convert.ToDouble() lèvera une exception avec des nombres en notation scientifique. Considérez ceci : double toDouble = Convert.ToDouble((-1/30000).ToString()) ; // échouera double dblParse = Double.Parse((-1/30000).ToString()) ; // fonctionne bien.

46voto

Jon Skeet Points 692016

Pour commencer, j'utiliserais double.Parse plutôt que Convert.ToDouble en premier lieu.

Quant à savoir si vous devez utiliser Parse o TryParse : pouvez-vous procéder si les données d'entrée sont mauvaises, ou s'agit-il d'une condition vraiment exceptionnelle ? Si c'est exceptionnel, utilisez Parse et le laisser exploser si l'entrée est mauvaise. Si c'est attendu et peut être géré proprement, utilisez TryParse .

6 votes

Jon, pouvez-vous expliquer pourquoi vous préférez double.Parse à Convert.ToDouble ?

10 votes

@dnorthut : Je veux rarement que null soit converti en 0 (ce que fait Convert.ToDouble), en fait. C'est aussi généralement plus flexible. J'ai juste tendance à opter pour les méthodes spécifiques...

7voto

Aaron Palmer Points 4256

Si vous n'avez pas l'intention de traiter l'exception, utilisez TryParse. TryParse est plus rapide parce qu'il n'a pas à traiter toute la trace de la pile de l'exception.

7voto

Konrad Rudolph Points 231505

J'essaie généralement d'éviter les Convert (c'est-à-dire que je ne l'utilise pas) car je la trouve très confuse : le code donne trop peu d'indications sur ce qui se passe exactement ici puisque Convert permet à un grand nombre de conversions sémantiquement très différentes de se produire avec le même code. Il est donc difficile pour le programmeur de contrôler ce qui se passe exactement.

Mon conseil, par conséquent, est de ne jamais utiliser cette classe. Elle n'est pas vraiment nécessaire non plus (sauf pour le formatage binaire d'un nombre, car la classe normale ToString des classes de nombres n'offre pas de méthode appropriée pour le faire).

7voto

Steven Points 332

À moins d'être sûr à 100% de vos entrées, ce qui est rarement le cas, vous devriez utiliser 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 vitesse de l'analyse devient secondaire lorsque vous lâchez une exception, car il n'y a pas grand-chose de plus lent qu'une exception.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X