J'ai un programme écrit en C # où il y a beaucoup de comparaisons entre intenses et chaînes.
Donc, pour des raisons de performance, je voudrais juste savoir ce qui est plus efficace? P>
Si nous avons: p> ou p>
11 Réponses :
Plus le nombre est grand que je vais aller pour la première méthode. une. Si B n'est pas un nombre, il échouera avant d'essayer de comparer. b. la chaîne est comparée par la longueur et le nombre à la fois. P>
L'analyse d'une chaîne à un int32 nécessite plus de performances et est plus sensible aux erreurs. Vous devrez vous assurer que le INT32.PARSE réussira en premier lieu. Vous pouvez également utiliser une alternative pour '=='. Utilisez des angles (), cela plus facile à lire et à comprendre.
if(b.Equals(a))
{
}
1.Qui ("1") compilera, mais retourne faux. Ce n'est pas ce qu'il veut.
Quelques commentaires mentionnés à exécuter un outil de profilage pour prouver qui a une meilleure performance.
Ceci est un bon moyen, mais le moyen le plus simple de vérifier les performances d'énoncés spécifiques est de les mettre en boucle et d'utiliser la classe de chronomètre. P>
Jeff Atwood a demandé de faire ce genre de timing plus simple dans Cette question . Dans cette question et cette réponse, vous trouverez également de bons exemples de code et des détails de base. P>
Heres un exemple de travail très simple: p> sur mon ordinateur sorties: p> a == int.parse (b) millisecondes: 521 P> A.Tostring () == B millisecondes: 697 P> donc dans ce simple Scénario int.parse () est légèrement plus rapide, mais pas assez pour vraiment s'inquiéter de. p> p>
Est-ce la classe de chronomètre de débogage? Soz im un peu d'un débutant quand il s'agit de c # :)
C'est la classe System.Diagnostics.stopwatch. Vous devriez être capable de taper: chronomètre sw = nouveau chronomètre (); et commencez-le (c'est dans System.dll).
1000000 Runs => Différence inférieure à 200ms. Cela peut ne pas être un cas pour une optimisation. Si les requêtes sont lentes, utilisez un profileur. S'ils sont assez rapides, pourquoi perdrez-vous du temps optimiser?
Toute raison que vous démarrez le chronomètre deux fois pour le premier tour, y compris l'affectation de la variable? Ne devrait pas être assez grand pour obliger les résultats, mais toujours ...
@Freed, parce que je tapitais plus vite, mon cerveau pourrait suivre;) Beau ramassage! J'ai supprimé le premier départ ().
Pouvez-vous essayer la chaîne comme un hexadécimal? Je suis surpris (je ne doute pas le résultat) que c'est plus rapide compte tenu de tout le logique int.parse doit effectuer
@Chris, la logique n'est-elle pas que Tostring () a à jouer très bien ce qu'est-ce que l'analyse () doit faire ..?
Si vous essayez de tostrer ("D"), il peut être plus rapide. Cela utilise la fonction INT32TODECSTR dans le CLR. Aucun format (juste tostring ()) est équivalent à "g" qui utilise le numéroTostring () qui analyse un format. Donc @freed oui je me trompe ci-dessus
Tostring ("D") n'est pas plus rapide du tout. string.format ("{0: d}", a) est beaucoup plus lent
Aussi j'ai lu somwhere (MSDN) en utilisant ce qui suit est plus rapide que == pour les comparaisons de chaîne
Quel est l'avantage d'utiliser des majuscules lors de la comparaison des nombres?
De plus, il est plus rapide d'utiliser un égal avec ordinalignorecase (ou invariantCultureCuceCase) que d'affecter de nouvelles chaînes majuscules.
Il existe de nombreuses façons de représenter le même numéro qu'une chaîne ... p>
J'ai en fait profilé cela en utilisant quelques exemples et des boucles chronométrées. Il s'avère d'analyser les victoires pour de petits entiers et des gains de totring pour les grands. Cette différence est si petite que cela ne devrait pas être une préoccupation cependant, car d'autres l'ont mentionné, vous êtes susceptible de faire un meilleur choix en pensant aux cas où la chaîne ne représente pas un entier du tout.
Votre choix est entre les
Code Inscription A STRY> int a = 5;
string b = "5";
//Assuming these two values are input received by the application at runtime
if (string.Compare(b, a.ToString(), StringComparison.Ordinal) != -1)
{
}
Je doute que l'un ou l'autre appel, vous aurez vraiment un impact considérable sur votre candidature à moins que vous ne créez vraiment quelque chose à grande échelle.
Les deux techniques créent une nouvelle chaîne, cependant Vous pouvez comparer le C ++ que le CLR utilise pour Tostring () ICI : Recherchez P> le c # p> Je pourrais me tromper sur fcimpl3, corrigez-moi si je suis. P> p> int.tostring () code> doit exécuter beaucoup moins de tâches que int.parse (). code> p> < p> int.tostring () code> est effectué en interne dans le CLR (Comnumber). int.parse () code> est fait à l'intérieur de BCL Source à l'aide de number.parsetin32 () code> -> number.stringtonumber () code> -> number.parsenumber () code >. P> Parsenumber code> Effectue un nombre énorme de chèques, donc d'un doigt dans l'air, devinez que vous imaginiez Int.Tostring () est plus rapide. Comme d'autres les ont mentionnés, un test de performance approprié avec le chronomètre Une classe sera une meilleure façon de le savoir. Vous voudrez essayer cela avec le format de numéro que vous attendez: décimal, hexal. P>
Numbertostring CODE> (qui est utilisé pour TOSTRING () et d'autres formats) qui est utilisé dans fcimpl3 code>, appelé par int.tostring () sous forme d'un extern code> appel. li>
int32todecstr code> est utilisé pour le formateur "D". li>
ul>
interne, tostring and parse effectuez ce qui suit:
parse strong> p> tostring strong> p> p> p> string=""
while value > 0
string.insert_at_front value % 10 // so that 0 -> '0' and 6 -> '6'
value /= 10
// on IA32, the % and / can be done at the same time but requires
// a 64bit source for 32bit values
Vous avez déjà eu quelques bonnes réponses, mais laissez-moi ajouter quelques petits points. P>
L'un des risques connus avec les micro-repères est qu'un petit nombre de répétitions peut finir par mesurer le bruit de mesure (par exemple, les horaires peuvent être asymétriques par un courrier électronique entrant ou une IM), mais un grand nombre de répétitions Peut finir par mesurer les performances de votre collecteur de déchets (par exemple, si votre code crée et jete constamment des chaînes). P> li>
Quand je me trouve dans un endroit inconfortable en code, il est parfois utile de me demander: "Quelles hypothèses ou choix me mettent dans cette situation? Que pouvais-je faire différemment?" Par exemple (juste deviner), quand vous avez écrit "... où il y a beaucoup de comparaisons entre * [sic] * et cordes", cela implique-t-il que vous utilisez des mêmes valeurs à plusieurs reprises (par exemple, comparer de nouvelles valeurs contre les valeurs précédentes)? Si tel est le cas, pourriez-vous convertir chaque chaîne en int et mettre en cache la valeur convertie pour la réutilisation ultérieure, au lieu de devoir le convertir à nouveau plus tard? P> LI> ol>
Mon cas qui m'a amené ici était de vérifier si "5" == 5 dans un cas de commutation et que je recevrai toujours des chiffres compris entre 0 et 9, j'ai découvert que le moyen le plus rapide est:
EDIT: Comme Dirk Horsten a demandé.
Faux que je suis. J'ai mentionné dans mon poste que j'utilise cela sur un étui de commutation afin que je vais utiliser dans tous mes cas les valeurs ASCII afin de ressembler à ce que:
(int) b [0] == 53
code>
Donc, je prends le caractère poing de la chaîne "5" (B [0]) et je l'ai jeté une valeur ACSII qui est 53 et après cela. Voici les résultats:
A == int.parse (b) millisecondes: 194
A.Tostring () == B millisecondes: 142
A == (int) (b [0]) millisecondes: 8
code>
Même si c'est un cas très inhabituel, la différence sur une matrice massive est évidente; p>
commutateur ((int) b [0])
{
CAS 48: CONSOLE.WRITINE ("0");
Pause;
CAS 49: CONSOLE.WRITINE ("1");
Pause;
cas 50: console.writeine ("2");
Pause;
Cas 51: Console.Writeine ("3");
Pause;
Cas 52: Console.Writeine ("4");
Pause;
CAS 53: CONSOLE.WRITINE ("5");
Pause;
CAS 54: Console.Writeine ("6");
Pause;
CAS 55: CONSOLE.WRITINE ("7");
Pause;
CAS 56: CONSOLE.WRITINE ("8");
Pause;
Cas 57: Console.Writeine ("9");
Pause;
}
code>
Et pour un bon ordre, voici les résultats que vous m'avez demandé:
A == int.parse (b) millisecondes: 184
A.Tostring () == B millisecondes: 135
A + 48 == (int) b [0] millisecondes: 8
code>
Comme vous pouviez voir, il n'y a pas une telle grande différence simplement en ajoutant une addition. P>
Votre réponse est brillante :) mais mal :( la bonne chose à faire est A + 48 == (int) (B [0]) code>, car (int) ("0" [ 0]) == 48 code>. Veuillez exécuter votre référence avec ce code et nous dire les résultats.
Stock Réponse Pour ces questions: Avez-vous essayé de la profiler pour vos données?
Im un noob: / Comment allais-je aller au profilage de cela?
Exécutez les deux variantes dans une boucle de quelques milliers ou millions d'itérations et mesurez le temps nécessaire.
Vous utilisez un outil de profilage pour mesurer le temps de chaque méthode.
Il est plus efficace de comparer INT. La vraie question est cependant combien coûtent
int.tostring code> etint.parse code>.int.parse code> est probablement beaucoup plus cher, mais ne peut pas confirmer cela pour le moment.Mesurer le temps avec le chronomètre de débogage en C #?
Avant de perdre du temps en profilant mal avec des boucles, vous devriez vous demander: est-ce un véritable goulot d'étranglement?
@Guillaume Eh bien il y a potentiellement des hundrends - des milliers de comparaisons par demande, donc im inclinées pour dire oui
KOBI> Tostring peut également être coûteux, une chaîne est allouée sur le tas. Construire une corde peut être plus cher que la lecture d'une ...
@Le_butcher Vous êtes enclin, vous devez savoir, vous devriez essayer avec un vrai profileur. Vous pouvez facilement en trouver un en recherchant SO ou Google.
AQTime est un bon profileur et vous pouvez télécharger un procès, je pense. Vous devez vérifier cependant que vous ne saboterez pas votre propre test - le compilateur est assez intelligent et peut utiliser des techniques pour raccourcir le temps de processus si vous faites la même fonction exacte encore et encore et encore ...
@Butcher utilise la liste des codes A J'ai fourni contre celui que vous avez mentionné dans la question et la réponse sélectionnée pour de meilleurs résultats.