Moyen le plus rapide pour convertir un object en double?

Quel est le moyen le plus rapide de convertir un object en double? Je suis à un morceau de code en ce moment, qui se lit comme suit:

var d = double.TryParse(o.ToSsortingng(), out d); // o is the Object... 

Les premières pensées ont été de réécrire ceci comme

 var d = Convert.ToDouble(o); 

mais serait-ce réellement plus rapide?

EDIT: En plus d’exécuter le profil (d’ailleurs, je recommande vivement JetBrains dotTrace à tous les développeurs), j’ai exécuté Reflector, ce qui m’a aidé à trouver ce qui suit (plus ou moins la partie pertinente du code):

 if (o is IConvertible) { d = ((IConvertible)o).ToDouble(null); } else { d = 0d; } 

Le code original double.TryParse() exécuté en 140ms. Le nouveau code s’exécute en 34ms. Je suis presque sûr que c’est le chemin d’optimisation que je devrais emprunter, mais avant de le faire, est-ce que quelqu’un voit quelque chose de problématique avec mon code “optimisé”? Merci d’avance pour vos commentaires!

Vous devez en faire énormément pour pouvoir passer tout votre temps là-dessus. Cependant, je ne suis pas ici pour juger:

Donc, votre code est le suivant:

 if (o is IConvertible) { d = ((IConvertible)o).ToDouble(null); } else { d = 0d; } 

Je me demande si vous seriez mieux avec cela

 IConvertible convert = o as IConvertible; if (convert != null) { d = convert.ToDouble(null); } else { d = 0d; } 

Vous sauve le double casting.

J’ai essayé les méthodes suivantes.

  • double.TryParse
  • double.Parse
  • Convertir en double

J’ai utilisé le code suivant.

 public static void Main() { ssortingng text = "3.14"; var timer = new Stopwatch(); timer.Start(); for (int i = 0; i < 10000000; i++) { double d; d = Convert.ToDouble(text); //double.TryParse(text, out d); //d = double.Parse(text); } timer.Stop(); Console.WriteLine("Time=" + timer.Elapsed.ToString()); Console.ReadLine(); } 

Sur ma machine, j'ai vu ces résultats. J'ai en moyenne 3 courses différentes.

  • double.TryParse = 4,45 secondes
  • double.Parse = 4.45 secondes
  • Convert.ToDouble = 4,75 secondes

Bien sûr, j'ai utilisé une chaîne qui était convertible. Si la chaîne n'est pas convertible, je soupçonne fortement double.TryParse sera le plus rapide de loin.

Créez une petite application de test à l’aide de System.Diagnostics.Stopwatch et voyez laquelle apparaît le plus rapidement. Bien que je dirais que cela ne ferait pas une différence valable. J’irais pour Convert.ToDouble purement pour la lisibilité.

Premièrement, si vous voulez vraiment savoir ce qui est le plus rapide, vous devez écrire un test rapide (en utilisant les données que vous comptez traiter) et chronométrer chaque option. Sans savoir ce que o est (ou est susceptible d’être), il est très difficile de juger. Je suppose que vous ne verrez pas beaucoup de différence.

Deuxièmement, à moins que vous appeliez ce morceau de code dans une partie extrêmement critique de votre code et que vous l’appeliez des milliers de fois pour démarrer, je doute que cela compte vraiment. Écrivez bien, nettoyez le code, puis optimisez.

Vous pouvez essayer différentes choses en fonction de la nature de votre travail. Il pourrait être

a) un double boxé, et vous voulez juste le déballer:

 object o = 53.2; double d = (double)o; 

b) un autre type, valeur ou référence ayant une conversion en double disponible (implémente IConvertible.ToDouble ()) que vous souhaitez utiliser

 object o = 53.2M; // a System.Decimal double d = Convert.ToDouble(o); 

ou

c) quelque chose qui a une représentation de chaîne par défaut qui peut être analysée comme un double

 object o = "53.2"; double d; bool convertedOK = double.TryParse(o.ToSsortingng(), out d); 

L’option c est en quelque sorte le plus long chemin à parcourir; vous prenez votre object, lui demandant sa représentation sous forme de chaîne, puis vous essayez d’parsingr cette chaîne pour obtenir un double. C’est maladroit si vous n’avez pas besoin de le faire, et dans votre exemple de 40 000 appels, cela va créer et ignorer 40 000 chaînes …

Si vous savez que votre object contiendra toujours quelque chose qui implémentera une conversion en double, vous pouvez ignorer tout cela et choisir l’option b. Et si vous savez que votre object ne sera qu’un double encadré, optez pour l’option la plus simple (a) pour le déballer.

Peut-être que quelque chose dans ce sens fonctionnerait pour vous, si vous ne savez vraiment pas ce que ce sera?

 double d = (o is double) ? (double)o : (o is IConvertible) ? (o as IConvertible).ToDouble(null) : double.Parse(o.ToSsortingng()); 

(Remarque: cela ne fonctionnera pas si o contient quelque chose qui implémente IConvertible mais ne peut pas être converti en double, ou si sa représentation sous forme de chaîne ne peut pas être analysée comme un double)

Je n’ai rien dit sur les vitesses relatives, mais je serais étonné que le déconditionnement ne soit pas beaucoup plus rapide que la conversion en chaîne, puis l’parsing syntaxique (à moins que l’optimiseur ne soit vraiment intelligent).

Un test rapide dans LINQPad à l’aide du chronomètre .NET suggère une grande différence.

 IEnumerable myData = new List() { "53.2", 53.2M, 53.2D }; const int iterations = 10000000; var sw = new Stopwatch(); var results = new List(); foreach (var o in myData) { sw.Reset(); sw.Start(); for (var i=0; i < iterations; i++) { double d = (o is double) ? (double)o : (o is IConvertible) ? (o as IConvertible).ToDouble(null) : double.Parse(o.ToString()); } sw.Stop(); results.Add($"{o.GetType()}: {iterations} iterations took {sw.ElapsedMilliseconds}ms"); } results.Dump(); 

sur mon PC donne les résultats suivants

 System.Ssortingng: 10000000 iterations took 1329ms System.Decimal: 10000000 iterations took 402ms System.Double: 10000000 iterations took 38ms