Ma question concerne les caractéristiques de performance des méthodes statiques par rapport aux méthodes d'instance et leur évolutivité. Supposons pour ce scénario que toutes les définitions de classe se trouvent dans un seul assembly et que plusieurs types de pointeurs discrets sont requis.
Considérer:
public sealed class InstanceClass
{
public int DoOperation1(string input)
{
// Some operation.
}
public int DoOperation2(string input)
{
// Some operation.
}
// … more instance methods.
}
public static class StaticClass
{
public static int DoOperation1(string input)
{
// Some operation.
}
public static int DoOperation2(string input)
{
// Some operation.
}
// … more static methods.
}
Les classes ci-dessus représentent un modèle de style d'assistance.
Dans une classe d'instance, la résolution de la méthode d'instance prend un moment pour s'opposer à StaticClass.
Mes questions sont:
Lorsque conserver l'état n'est pas un problème (aucun champ ou propriété n'est requis), est-il toujours préférable d'utiliser une classe statique?
Là où il y a un nombre considérable de ces définitions de classes statiques (disons 100 par exemple, avec un certain nombre de méthodes statiques chacune) cela affectera-t-il négativement les performances d'exécution ou la consommation de mémoire par rapport au même nombre de définitions de classe d'instance?
Lorsqu'une autre méthode de la même classe d'instance est appelée, la résolution d'instance se produit-elle toujours? Par exemple, en utilisant le mot-clé [this] comme
this.DoOperation2("abc")
dansDoOperation1
la même instance.
la source
this
pointe vers quelque chose quand une classe appelle une méthode d'instance sur elle-même?"Réponses:
En théorie, une méthode statique devrait fonctionner légèrement mieux qu'une méthode d'instance, toutes choses étant égales par ailleurs, en raison du
this
paramètre caché supplémentaire .En pratique, cela fait si peu de différence qu'il sera caché dans le bruit des diverses décisions du compilateur. (Par conséquent, deux personnes pourraient "prouver" l'une meilleure que l'autre avec des résultats en désaccord). Notamment, car le
this
est normalement passé dans un registre et est souvent dans ce registre pour commencer.Ce dernier point signifie qu'en théorie, nous devrions nous attendre à ce qu'une méthode statique qui prend un objet comme paramètre et fasse quelque chose avec lui soit légèrement moins bonne que l'équivalent en tant qu'instance sur ce même objet. Encore une fois, la différence est si légère que si vous essayez de la mesurer, vous finirez probablement par mesurer une autre décision du compilateur. (D'autant que la probabilité que cette référence soit dans un registre tout le temps est également assez élevée).
Les vraies différences de performances se résumeront à savoir si vous avez artificiellement des objets en mémoire pour faire quelque chose qui devrait naturellement être statique, ou si vous emmêlez des chaînes de passage d'objets de manière compliquée pour faire ce qui devrait naturellement être une instance.
D'où le numéro 1. Lorsque le maintien de l'état n'est pas un problème, il est toujours préférable d'être statique, car c'est à cela que sert la statique . Ce n'est pas un problème de performance, bien qu'il y ait une règle générale pour bien jouer avec les optimisations du compilateur - il est plus probable que quelqu'un se soit efforcé d'optimiser les cas d'utilisation normale que ceux qui présentent une utilisation étrange.
Numéro 2. Ne fait aucune différence. Il y a un certain montant de coût par classe pour chaque membre, en fonction de la quantité de métadonnées, de la quantité de code dans le fichier DLL ou EXE réel et de la quantité de code jit. C'est la même chose que ce soit une instance ou statique.
Avec l'élément 3,
this
est commethis
ça. Notez cependant:Le
this
paramètre est passé dans un registre particulier. Lors de l'appel d'une méthode d'instance dans la même classe, elle sera probablement déjà dans ce registre (à moins qu'elle n'ait été cachée et que le registre soit utilisé pour une raison quelconque) et par conséquent, aucune action n'est requise pour définir lethis
sur ce qu'il doit être défini. . Cela s'applique dans une certaine mesure, par exemple aux deux premiers paramètres de la méthode étant les deux premiers paramètres d'un appel qu'elle effectue.Comme il sera clair que ce
this
n'est pas nul, cela peut être utilisé pour optimiser les appels dans certains cas.Comme il sera clair que ce
this
n'est pas nul, cela peut rendre les appels de méthode intégrés plus efficaces à nouveau, car le code produit pour simuler l'appel de méthode peut omettre certaines vérifications nulles dont il pourrait avoir besoin de toute façon.Cela dit, les chèques nuls sont bon marché!
Il convient de noter que les méthodes statiques génériques agissant sur un objet, plutôt que les méthodes d'instance, peuvent réduire certains des coûts discutés à http://joeduffyblog.com/2011/10/23/on-generics-and-some-of- the-associated-overheads / dans le cas où cette statique donnée n'est pas appelée pour un type donné. Comme il le dit: «En passant, il s'avère que les méthodes d'extension sont un excellent moyen de rendre les abstractions génériques plus payantes».
Cependant, notez que cela ne concerne que l'instanciation d'autres types utilisés par la méthode, qui n'existent pas autrement. En tant que tel, cela ne s'applique vraiment pas à de nombreux cas (une autre méthode d'instance a utilisé ce type, un autre code ailleurs utilisé ce type).
Résumé:
Edit: Une note sur à quel point les vérifications nulles sont bon marché (ce que j'ai réclamé ci-dessus). La plupart des vérifications nulles dans .NET ne vérifient pas du tout null, elles continuent plutôt ce qu'elles allaient faire avec l'hypothèse que cela fonctionnera, et si une exception d'accès se produit, elle est transformée en un fichier
NullReferenceException
. En tant que tel, la plupart du temps lorsque conceptuellement le code C # implique une vérification nulle parce qu'il accède à un membre d'instance, le coût s'il réussit est en fait nul. Une exception serait certains appels intégrés, (car ils veulent se comporter comme s'ils appelaient un membre d'instance) et ils frappent simplement un champ pour déclencher le même comportement, donc ils sont également très bon marché, et ils peuvent encore souvent être laissés de côté de toute façon (par exemple, si la première étape de la méthode impliquait d'accéder à un champ tel quel).la source
this
ou via un paramètre explicite. Un impact plus important ici serait la proximité des données avec les données associées (les champs de type valeur ou les valeurs de tableau sont plus proches que les données des champs de type référence) et les modèles d'accès.obj.DoSomehting(2)
ce soit légèrement moins cher que,DoSomething(obj, 2)
mais comme je l'ai aussi dit, la différence est si légère et si dépendante de petites choses qui pourraient finir par être différentes dans la compilation finale que cela ne vaut pas la peine de s'inquiéter du tout. Si vous faites quelque chose d'aussi cher (par rapport au genre de différences de jeu ici) que la sérialisation de quelque chose sur une chaîne, c'est particulièrement inutile.ctor
nécessite toujours l'initialisation de tous les champs. Une fois que vous avez déjà une instance, cette réponse s'applique ("toutes choses égales par ailleurs"). Bien sûr, unecctor
méthode coûteuse peut également ralentir les méthodes statiques, mais ce n'est que lors du premier appel et s'applique également aux méthodes d'instance. Voir aussi docs.microsoft.com/en-us/previous-versions/dotnet/articles/…Je dirais, oui. En déclarant quelque chose,
static
vous déclarez une intention d'exécution sans état (ce n'est pas obligatoire, mais une intention de quelque chose auquel on pourrait s'attendre)Ne le pensez pas, sauf si vous êtes sûr que les classes statiques sont vraiment stetless, car sinon, il est facile de gâcher les allocations de mémoire et d'obtenir des fuites de mémoire.
Pas sûr, à propos de ce point (il s'agit uniquement d'un détail de mise en œuvre de CLR), mais pensez que oui.
la source
les méthodes statiques sont plus rapides mais moins POO, si vous allez utiliser des modèles de conception méthode statique probablement un mauvais code, pour mieux écrire la logique métier sans statique, des fonctions communes comme la lecture de fichiers, WebRequest, etc. mieux se rendre compte comme statique ... vos questions n'ont pas d'universel répondre
la source