Question

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

Qu'est-ce préférable de vérifier si la chaîne en cours 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
}

ou

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 d'algorithme d'analyse ci-dessous.

Mes questions: Quel chemin est plus rapide? Ce qui est plus sûr?

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

Était-ce utile?

La solution

Je l'ai fait un test non scientifique rapide en mode de sortie. J'ai utilisé deux entrées:. « 2,34523 » et « badinput » dans les deux méthodes et Iterated 1.000.000 fois

entrée valide:

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

Pas très différent, comme prévu. Pour toutes fins utiles, pour une entrée valide, ce sont les mêmes.

entrée non valide:

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

Eh bien .. il a été en cours d'exécution depuis longtemps. Je la chose rediffusé entier à l'aide de 1000 itérations et Convert.ToDouble avec une mauvaise entrée a pris 8,3 secondes. Calcul de la moyenne dehors, il faudrait plus de 2 heures. Je ne me soucie pas comment le test de base est, dans le cas d'entrée non valide, la levée d'exception de Convert.ToDouble va ruiner votre performance.

Alors, voici un autre vote pour TryParse avec quelques chiffres pour le sauvegarder.

Autres conseils

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

Quant à savoir si vous devez utiliser Parse ou TryParse: pouvez-vous procéder s'il y a des données d'entrée mal, ou est-ce vraiment une condition exceptionnelle? Si elle est exceptionnelle, utilisez Parse et laissez exploser si l'entrée est mauvais. S'il est prévu et peut être manipulé proprement, utilisez TryParse.

Les lignes directrices de conception .NET Framework vous recommandons d'utiliser les méthodes de essai. Éviter les exceptions est généralement une bonne idée.

Convert.ToDouble(object) fera ((IConvertible) object).ToDouble(null);

Ce qui appellera Convert.ToDouble(string, null)

Il est donc plus rapide d'appeler la version string.

Cependant, la version de la chaîne ne ceci:

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

Il est donc plus rapide de faire le double.Parse directement.

Si vous n'allez gérer l'exception aller avec TryParse. TryParse est plus rapide parce qu'il n'a pas à faire face à toute trace de la pile d'exception.

J'essaie généralement d'éviter la classe Convert (ce qui signifie: Je ne l'utilise pas) parce que je trouve très confus: le code donne trop peu de conseils sur ce qui se passe exactement ici depuis Convert permet beaucoup de conversions sémantiquement très différentes se produire avec le même code. Cela rend difficile à contrôler pour le programmeur ce qui se passe exactement.

Mon conseil est donc de ne jamais utiliser cette classe. Il est pas vraiment nécessaire, soit (sauf pour la mise en forme binaire d'un nombre, car la méthode ToString normale des classes numériques ne propose pas une méthode appropriée pour le faire).

Si vous n'êtes pas certain à 100% de vos entrées, ce qui est rarement le cas, vous devez 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 syntaxique devient secondaire lorsque vous jetez une exception, car il n'y a pas beaucoup plus lent que l'exception.

Beaucoup de haine pour la classe Convert ici ... Juste pour équilibrer un peu, il y a un avantage pour Convert - si vous êtes remis un objet,

Convert.ToDouble(o);

peut simplement renvoyer la valeur facilement si o est déjà un double (ou un int ou quoi que ce soit facilement coulable).

ou en utilisant Double.Parse Double.TryParse est très bien si vous l'avez déjà dans une chaîne, mais

Double.Parse(o.ToString());

doit aller make la chaîne à analyser d'abord et en fonction de votre entrée qui pourrait être plus cher.

Double.TryParse OMI.

Il est plus facile pour vous de gérer, vous saurez exactement où l'erreur est survenue.

Ensuite, vous pouvez y faire face comment bon vous semble si elle retourne false (i.e. ne pouvait convertir).

Je l'ai toujours préféré utiliser les méthodes de TryParse() parce qu'il va recracher le succès ou l'échec de conversion sans avoir à se soucier des exceptions.

Personnellement, je trouve la méthode TryParse plus facile à lire, que l'on vous voulez utiliser dépend de votre cas d'utilisation: si les erreurs peuvent être traitées au niveau local que vous attendez des erreurs et un bool de TryParse est bonne, sinon vous pourrait vouloir simplement laisser les exceptions voler.

J'attends la TryParse soit plus rapide aussi, car elle évite les frais généraux de gestion des exceptions. Mais utiliser un outil de référence, comme MINIBENCH Jon Skeet pour comparer les différentes possibilités.

Ceci est une question ancienne intéressante. J'ajoute une réponse parce que personne n'a remarqué deux ou trois choses à la question initiale.

Ce qui est plus rapide: Convert.ToDouble ou Double.TryParse? Ce qui est plus sûr: Convert.ToDouble ou Double.TryParse

Je vais répondre à ces deux questions (je vais mettre à jour la réponse plus tard), en détail, mais d'abord:

Pour la sécurité, la chose tous programmeur manqué à cette question est la ligne (Souligné par l'auteur):

  

Il ajoute que des données qui sont des nombres avec quelques chiffres (1000 1000,2 1000,34 - virgule est un séparateur dans les normes russes ).

Suivi par cet exemple de code:

Convert.ToDouble(regionData, CultureInfo.CurrentCulture);

Ce qui est intéressant est que si les feuilles de calcul sont en format numérique russe, mais Excel n'a pas correctement tapé les champs cellulaires, quelle est l'interprétation correcte des valeurs qui viennent d'Excel?

Voici une autre chose intéressante au sujet des deux exemples, en ce qui concerne la vitesse:

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

Cela va probablement générer MSIL qui ressemble à ceci:

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

Dans ce sens, on peut sans doute comparer le nombre total d'instructions MSIL effectuées par chaque programme -. Reviendrons plus tard que je mets à jour ce message

Je crois que le code devrait être correcte, claire et rapide ... Dans cet ordre!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top