Performances d'utilisation de méthodes statiques et d'instanciation de la classe contenant les méthodes

StackOverflow https://stackoverflow.com/questions/202631

Question

Je travaille sur un projet en C #. Le programmeur précédent ne connaissait pas la programmation orientée objet. La plupart du code est donc composé d’énormes fichiers (nous parlons autour de 4 000 à 5 000 lignes), répartis sur des dizaines et parfois des centaines de méthodes, mais sur une seule classe. Refactoriser un tel projet est une entreprise gigantesque et j’ai donc appris à vivre avec pour l’instant.

Chaque fois qu'une méthode est utilisée dans l'un des fichiers de code, la classe est instanciée puis la méthode est appelée sur l'instance de l'objet.

Je me demande s’il existe des pénalités de performance notables en procédant de cette façon? Dois-je rendre toutes les méthodes statiques " pour le moment " et, plus important encore, l'application en tirera-t-elle profit de quelque manière que ce soit?

Était-ce utile?

La solution

À partir de ici , un appel statique est 4 à 5 fois plus rapide. que de construire une instance chaque fois que vous appelez une méthode d’instance. Cependant, nous ne parlons toujours que de dizaines de nanosecondes par appel. Il est donc peu probable que vous remarquiez un avantage, sauf si vous avez des boucles très étroites qui appellent une méthode des millions de fois. Vous pouvez obtenir le même avantage en construisant une instance unique en dehors de cette boucle et la réutiliser.

Etant donné que vous devez modifier chaque site d'appels pour utiliser la méthode nouvellement statique, vous passerez probablement mieux à une refactorisation progressive.

Autres conseils

J'ai traité un problème similaire dans lequel je travaille. Le programmeur avant moi a créé 1 classe de contrôleurs où toutes les fonctions BLL ont été vidées.

Nous sommes en train de remodeler le système et avons créé de nombreuses classes de contrôleurs en fonction de ce qu'elles sont censées contrôler, par exemple.

UserController, GeographyController, ShoppingController ...

Dans chaque classe de contrôleur, ils ont des méthodes statiques qui appellent le cache ou le DAL en utilisant le modèle singleton.

Cela nous a donné 2 principaux avantages. Il est légèrement plus rapide (environ 2 à 3 fois plus rapide mais parlait ici en nanosecondes; P). L'autre est que le code est beaucoup plus propre

c'est-à-dire

ShoppingController.ListPaymentMethods()

au lieu de

new ShoppingController().ListPaymentMethods()

Je pense qu'il est logique d'utiliser des méthodes ou des classes statiques si la classe ne conserve aucun état.

Cela dépend de ce que cet objet contient d'autre - si l'objet " objet " est juste un tas de fonctions alors ce n'est probablement pas la fin du monde. Mais si l'objet contient un tas d'autres objets, son instanciation va appeler tous ses constructeurs (et ses destructeurs, lorsqu'il est supprimé) et vous risquez d'obtenir une fragmentation de la mémoire, etc.

.

Cela dit, il ne semble pas que la performance soit votre plus gros problème pour le moment.

Vous devez déterminer les objectifs de la réécriture. Si vous voulez avoir une bonne testable, extensible & amp; maintenable code OO alors vous pouvez essayer d'utiliser des objets et leurs méthodes d'instance. Après tout, c’est la programmation orientée objet dont nous parlons ici, pas la programmation orientée classe.

Il est très simple de simuler et / ou de simuler des objets lorsque vous définissez des classes qui implémentent des interfaces et que vous exécutez des méthodes d'instance. Cela rend les tests unitaires approfondis rapides et efficaces.

Si vous souhaitez également respecter les principes OO (consultez SOLID à l'adresse http: //en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29 ) et / ou utilisez des modèles de conception, vous ferez certainement beaucoup de développement basé sur des instances, sur des interfaces et sur l'utilisation de nombreuses méthodes statiques.

En ce qui concerne cette suggestion:

  
    

Il me semble stupide de créer un objet JUST afin que vous puissiez appeler une méthode qui     n'a apparemment aucun effet secondaire sur l'objet (d'après votre description, je suppose cela).

  

Je le vois souvent dans les boutiques Internet et cela viole l’encapsulation, un concept clé d’OO. Je ne devrais pas être en mesure de dire si une méthode a des effets secondaires par le fait qu'elle soit ou non statique. En plus de rompre l'encapsulation, cela signifie que vous devrez changer les méthodes statiques en instances si / lorsque vous les modifiez pour avoir des effets secondaires. Je vous suggère de lire le principe Open / Closed de celui-ci et de voir comment l'approche suggérée, citée ci-dessus, fonctionne dans cet esprit.

Rappelez-vous ce vieux châtaignier, "l'optimisation prématurée est la racine de tout le mal". Je pense que dans ce cas, cela signifie que vous ne devez pas franchir des obstacles en utilisant des techniques inappropriées (par exemple, la programmation orientée classe) tant que vous ne saurez pas que vous avez un problème de performances. Même alors, corrigez le problème et recherchez le plus approprié.

Les méthodes statiques sont beaucoup plus rapides et utilisent beaucoup moins de mémoire. Il y a cette idée fausse que c'est juste un peu plus rapide. C'est un peu plus rapide tant que vous ne le mettez pas en boucle. Au fait, certaines boucles paraissent petites mais ne le sont pas car l'appel de méthode contenant la boucle est aussi une autre boucle. Vous pouvez faire la différence dans le code qui exécute les fonctions de rendu. Beaucoup moins de mémoire est malheureusement vraie dans de nombreux cas. Une instance permet de partager facilement des informations avec des méthodes soeurs. Une méthode statique demandera l'information quand il en aura besoin.

Mais comme dans le cas des voitures, la vitesse entraîne des responsabilités. Les méthodes statiques ont généralement plus de paramètres que leurs homologues d'instance. Dans la mesure où une instance prend en charge la mise en cache des variables partagées, vos méthodes d'instance seront plus jolies.

ShapeUtils.DrawCircle(stroke, pen, origin, radius);

ShapeUtils.DrawSquare(stroke, pen, x, y, width, length);

VS

ShapeUtils utils = new ShapeUtils(stroke,pen);

util.DrawCircle(origin,radius);

util.DrawSquare(x,y,width,length);

Dans ce cas, chaque fois que les variables d'instance sont utilisées par toutes les méthodes, les méthodes d'instance en valent vraiment la peine. Les instances ne concernent pas l’Etat, il s’agit de PARTAGER. Bien que STATE COMMUN soit une forme naturelle de PARTAGE, elles ne sont pas identiques. La règle générale est la suivante: si la méthode est étroitement associée à d'autres méthodes - ils s'aiment tellement que l'un d'eux s'appelle, mais les autres doivent être appelés aussi et ils partagent probablement la même tasse d'eau-- -, il devrait être fait exemple. Traduire des méthodes statiques en méthodes d'instance n'est pas si difficile. Vous devez seulement prendre les paramètres partagés et les mettre en tant que variables d'instance. L'inverse est plus difficile.

Vous pouvez également créer une classe proxy qui reliera les méthodes statiques. Bien que cela puisse sembler plus inefficace en théorie, la pratique raconte une histoire différente. En effet, chaque fois que vous devez appeler un DrawSquare une fois (ou dans une boucle), vous passez directement à la méthode statique. Mais chaque fois que vous l'utiliserez encore et encore avec DrawCircle, vous utiliserez le proxy d'instance. Un exemple est les classes System.IO FileInfo (instance) vs File (statique).

Les méthodes statiques sont testables. En fait, même plus testable qu'une instance une fois. La méthode GetSum (x, y) serait très testable non seulement pour le test unitaire, mais également pour le test de charge, le test intégré et le test d'utilisation. Les méthodes d'instance sont bonnes pour les tests d'unités mais horribles pour tous les autres tests (ce qui compte plus que les tests d'unités BTW), c'est pourquoi nous avons tant de bogues ces jours-ci. Ce qui rend TOUTES les méthodes non testables sont les paramètres qui n'ont pas de sens comme (Sender s, EventArgs e) ou un état global comme DateTime.Now. En fait, les méthodes statiques sont si efficaces en termes de testabilité que vous voyez moins de bugs dans le code C d’une nouvelle distribution Linux que votre programmeur OO moyen (il est plein de s *** je sais).

Je pense que vous avez partiellement répondu à cette question de la manière dont vous l'avez posée: existe-t-il des pénalités notables dans le code que vous avez?

Si les pénalités ne sont pas perceptibles, vous ne devez rien faire du tout. (Bien que cela va sans dire, la base de code gagnerait considérablement à une refactorisation progressive en un modèle OO respectable).

Je suppose que ce que je veux dire, c’est qu’un problème de performance n’est un problème que lorsque vous remarquez que c’est un problème.

Cela me semble ridicule de créer un objet JUST afin de pouvoir appeler une méthode qui n’a apparemment aucun effet secondaire sur l’objet (de votre description, j’assume cela). Il me semble qu'un meilleur compromis consisterait à avoir plusieurs objets globaux et à les utiliser. De cette façon, vous pouvez placer les variables normalement globales dans les classes appropriées afin qu'elles aient une portée légèrement inférieure.

À partir de là, vous pouvez déplacer progressivement la portée de ces objets pour qu'elle devienne de plus en plus petite jusqu'à ce que vous ayez une conception POO décente.

Là encore, l'approche que I utiliserait probablement est différente;).

Personnellement, je me concentrerais probablement sur les structures et les fonctions qui les exploitaient et tentais de les convertir en classes avec des membres peu à peu.

En ce qui concerne l'aspect performance de la question, les méthodes statiques devraient être légèrement plus rapides (mais pas beaucoup), car elles ne nécessitent pas la construction, la transmission et la déconstruction d'un objet.

Ce n'est pas valide en PHP,
La méthode objet est plus rapide:
http://www.vanylla.it/tests/static-method-vs -object.php

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top