2009-05-19 6 views
1

Je voudrais savoir ce qui est plus rapide. Aide moi.Différence entre une variable locale et une variable appelée à partir d'une méthode? C#

J'ai une variable déclarée dans une méthode comme ceci:

public static Regex FindNumber() 
{ return new Regex(@"\d+", RegexOptions.IgnoreCase | RegexOptions.Compiled); } 

Comme vous pouvez le voir renvoie une expression régulière.

J'ai aussi une autre méthode qui ressemble à ceci:

private static string TestOne(string RawData) 
{ 
    Regex rgxFindNumber = FindNumber(); 
    Regex rgxFindDays = FindDays(); 
    for (int i = 0; i < mc.Count; i++) 
    { 
     int days = Convert.ToInt32(rgxFindNumber.Match(rgxFindDays.Match(mc[i].Value).Value).Value); 
    } 
    return RawData; 
} 

maintenant est la méthode testone va être plus rapide ou est testtwo?

 private static string TestTwo(string RawData) 
{ 
    for (int i = 0; i < mc.Count; i++) 
    { 
     int days = Convert.ToInt32(FindNumber().Match(FindDays().Match(mc[i].Value).Value).Value); 
    } 
    return RawData; 
} 

maintenant im curieux parce que testone peut obtenir appelé beaucoup aweful dans mon code et je voudrais donc savoir ce qui serait mieux à mettre en œuvre.

Merci les gars.

** Edit: ** Le code que j'utilise a une classe extrêmement grande. C'est un analyseur de texte pour un jeu de stratégie basé sur le texte. J'essaie de refactoriser un peu et c'est ce que je me demande ici. Si je crée une variable privée pour le Regex, ne serait-il pas exécuté chaque fois que la classe est accédée? C'est ma question pour vous.

+0

D'ABORD établir des objectifs de performance significatifs. Deuxièmement, mesurer les progrès par rapport à ces objectifs. TROISIEME, si vous n'avez pas atteint vos objectifs, utilisez un profileur pour trouver la chose la plus lente. QUATRIÈME, corrigez-le. Répétez jusqu'à ce que vous atteigniez votre objectif. Chaque étape est cruciale. La seule façon de répondre à votre question est de la "vérifier" et de mesurer le résultat pour voir s'il est significatif. Personne assis à un bureau lisant votre question ne peut savoir quelle est la différence entre les machines de vos clients ou si cette différence est significative pour vos clients, ou si c'est même là que vous devriez chercher à optimiser. –

Répondre

4

TestOne sera plus rapide que TestTwo, parce que vous n'êtes pas créer une nouvelle expression régulière pour chaque itération de la boucle.

Cela a deux avantages:

  • Le temps utilisé pour analyser et construire les objets pour la regex est effectuée qu'une seule fois, au lieu de mc.Count fois
  • moins de pression sur la collecte des ordures depuis moins d'objets sont construits.

Cependant, je voudrais aller un peu plus loin. Si vous renvoyez toujours cette même expression régulière et que vous êtes préoccupé par la vitesse, je mettrais cet objet regex en cache dans un champ statique.

Par exemple, vous pourriez considérer ceci:

private static Regex _FindNumber; 
public static Regex FindNumber() 
{ 
    if (_FindNumber == null) 
     _FindNumber = new Regex(@"\d+", RegexOptions.IgnoreCase | RegexOptions.Compiled); 
    return _FindNumber; 
} 

Cela créerait un seul objet, au total, et le garder autour.

Cependant, et voici ma vraie réponse.

Pour savoir lequel sera le plus rapide, vous devrez mesurer votre code, éventuellement avec ma variante lancée, puis décider. Ne décidez jamais des optimisations sans données concrètes, vous pourriez finir par passer du temps à réécrire du code, ce qui peut introduire de nouveaux bugs, qui nécessiteront des corrections, sur lesquelles vous passerez plus de temps, seulement 1% de performance supplémentaire.

Les grandes optimisations sont faites de manière algorithmique, comme changer le type d'algorithme de tri, et seulement après, si nécessaire, vous passez à des optimisations locales comme le réglage de boucle. Cela dit, j'éviterais au moins de construire l'objet dans la boucle, c'est du bon sens.

+0

Je vais répéter ce commentaire comme indiqué sur la réponse womps, car il s'applique toujours. Le code que j'utilise a une classe extrêmement grande. C'est un analyseur de texte pour un jeu de stratégie basé sur le texte. J'essaie de refactoriser un peu et c'est ce que je me demande ici. Si je crée une variable privée pour le Regex, ne serait-il pas exécuté chaque fois que la classe est accédée? C'est ma question pour vous. –

+0

Scott: Le code fourni ci-dessus crée l'expression régulière stockée dans _FindNumber la première fois que la propriété statique FindNumber est accédée et qu'elle continuera d'exister jusqu'à la fin du programme. – Powerlord

+0

Chaque fois que vous appelez la méthode qui retourne un nouvel objet Regex, vous obtenez un nouvel objet Regex, qui prendra du temps à construire et ajoutera une pression GC.Si vous mettez en cache cet objet de sorte que la prochaine fois que vous appelez la même fonction, il récupère simplement l'objet précédemment généré, vous gagnez du temps et la pression de la CG. Si vous appelez la fonction, et qu'elle ne cache pas, dans une boucle, chaque itération de boucle prendra plus de temps car elle construit plus d'objets et ajoute plus de pression GC. Est-ce que ça répond à votre question? Sinon, soyez précis. –

1

Je crois que TestOne sera plus rapide parce que dans TestTwo vous créez un nouvel objet Regex chaque fois que vous bouclez. Si FindDays est implémenté de la même manière que FindNumber, ce sera encore pire car vous allez créer deux objets.

1

Techniquement, TestOne sera plus rapide, car TestTwo ajoute un cadre de pile en appelant FindNumber().

Je ne sais pas combien de différence cela fera, je doute que ce soit autant. Votre méthode est statique, donc c'est juste la création de l'objet, ce qui devrait être assez rapide.

Ma question est pourquoi utilisez-vous un appel de fonction pour retourner la même chaîne encore et encore? Pourquoi ne déclarez-vous pas simplement une vraie variable?

Comme,

private static Regex _findNumber = new Regex(@"\d+", RegexOptions.IgnoreCase | RegexOptions.Compiled); 
+0

Le code que j'utilise a une classe extrêmement grande. C'est un analyseur de texte pour un jeu de stratégie basé sur le texte. J'essaie de refactoriser un peu et c'est ce que je me demande ici. Si je crée une variable privée pour le Regex, ne serait-il pas exécuté chaque fois que la classe est accédée? C'est ma question pour vous. –

+1

Chaque fois que la classe est accessible? Absolument pas. Chaque fois que la classe est créée, assurez-vous de créer une variable privée pour cela. Mais déréférencer une variable va être plus rapide que d'appeler une fonction pour faire exactement la même chose. – womp

+0

womp, j'aurais alors environ 100 variables privées dans une classe en raison de sa taille, mais sur n'importe quelle instance, seulement environ 3 ou 4 ou ces variables sont utilisées chaque fois que j'ai créé une classe. Je suis un programmeur basé sur le Web, donc pour autant que je sache, les classes sont recréées à chaque fois qu'une publication est faite et qu'une méthode à l'intérieur de la classe est appelée. Ai-je raison? Donc, puisque je n'utilise que 3 ou 4 de ces variables nouvellement créées chaque fois que la classe est 'créée', il vaudrait mieux que je mette chacun dans une méthode. Est-ce exact? –

Questions connexes