En théorie, une méthode statique devrait être légèrement plus performante qu'une méthode d'instance, toutes choses égales par ailleurs, en raison de l'ajout d'un élément caché supplémentaire. this
paramètre.
En pratique, cela fait si peu de différence que cela sera caché dans le bruit des diverses décisions du compilateur. (Ainsi, deux personnes pourraient "prouver" que l'un est meilleur que l'autre avec des résultats divergents). D'autant plus que le this
est normalement transmis dans un registre et se trouve souvent dans ce registre au départ.
Ce dernier point signifie qu'en théorie, nous devrions nous attendre à ce qu'une méthode statique qui prend un objet en paramètre et en fait quelque chose soit légèrement moins bonne que l'équivalent en instance sur ce même objet. Encore une fois, la différence est si mince que si vous essayez de la mesurer, vous finirez probablement par mesurer une autre décision du compilateur. (D'autant plus que la probabilité que cette référence soit dans un registre pendant tout ce temps est également assez élevée).
Les vraies différences de performances se résument à savoir si vous avez artificiellement placé 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 la conservation de l'état n'est pas une préoccupation, il est toujours préférable d'être statique, parce que c'est à ça que servent les statiques . Ce n'est pas un problème de performance, bien qu'il y ait une règle générale qui consiste à jouer gentiment avec les optimisations du compilateur - il est plus probable que quelqu'un ait fait l'effort d'optimiser les cas qui se présentent dans le cadre d'une utilisation normale que ceux qui se présentent dans le cadre d'une utilisation étrange.
Numéro 2. Ça ne fait aucune différence. Il y a un certain coût par classe pour chaque membre en termes de quantité de métadonnées, de quantité de code dans le fichier DLL ou EXE et de quantité de code ajouté. C'est la même chose qu'il s'agisse d'instance ou de statique.
Avec le point 3, this
est comme this
fait. Toutefois, notez bien :
-
Le site this
est passé dans un registre particulier. Lors de l'appel d'une méthode d'instance au sein de la même classe, le paramètre sera probablement déjà dans ce registre (à moins qu'il n'ait été caché et que le registre n'ait été utilisé pour une raison ou une autre). this
à ce qu'il doit être réglé. Cela s'applique dans une certaine mesure, par exemple, aux deux premiers paramètres de la méthode qui sont les deux premiers paramètres d'un appel qu'elle effectue.
-
Puisqu'il sera clair que this
n'est pas nulle, cela peut être utilisé pour optimiser les appels dans certains cas.
-
Puisqu'il sera clair que this
n'est pas nulle, cela peut rendre les appels de méthode inlined plus efficaces, car le code produit pour simuler l'appel de méthode peut omettre certains contrôles de nullité dont il pourrait avoir besoin de toute façon.
-
Cela dit, les contrôles nuls ne sont pas chers !
Il est intéressant 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 à l'article 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 lui-même : "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, il ne s'applique pas vraiment à de nombreux cas (une autre méthode d'instance a utilisé ce type, un autre code quelque part ailleurs a utilisé ce type).
Résumé :
- Les coûts de performance de l'instance par rapport à la statique sont généralement négligeables.
- Les coûts qui en découlent sont généralement liés à l'utilisation abusive de l'électricité statique, par exemple, ou vice-versa. Si vous ne faites pas entrer en ligne de compte votre choix entre statique et instance, vous avez plus de chances d'obtenir le bon résultat.
- Il existe de rares cas où les méthodes génériques statiques d'un autre type entraînent la création de moins de types que les méthodes génériques d'instance. parfois ont un petit avantage à devenir rarement utilisées (et "rarement" fait référence aux types avec lesquels elles sont utilisées pendant la durée de vie de l'application, pas à la fréquence à laquelle elles sont appelées). Une fois que vous aurez compris de quoi il parle dans cet article, vous verrez que cela n'a rien à voir avec la plupart des décisions de type statique-vs-instance de toute façon. Edit : Et cela n'a ce coût qu'avec ngen, pas avec le code jitted.
Edit : Une note sur la façon dont les contrôles de nullité sont bon marché (ce que j'ai prétendu ci-dessus). La plupart des null-checks en .NET ne vérifient pas du tout l'existence de null, ils continuent plutôt ce qu'ils allaient faire en supposant que ça va fonctionner, et si une exception d'accès se produit, elle est transformée en un NullReferenceException
. Ainsi, la plupart du temps, lorsque le code C# implique conceptuellement un contrôle de nullité 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 inlined, (parce qu'ils veulent se comporter comme s'ils appelaient un membre d'instance) et ils frappent juste un champ pour déclencher le même comportement, donc ils sont aussi 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 implique l'accès à un champ tel quel).