web-dev-qa-db-fra.com

Quel est le "coût" de la réflexion .NET?

Duplicata possible:
Quel est le coût de la réflexion .NET?

Je suis actuellement dans une mentalité de programmation dont la réflexion est ma meilleure amie. Je l'utilise beaucoup pour le chargement dynamique de contenu qui permet une "implémentation lâche" plutôt que des interfaces strictes, ainsi que de nombreux attributs personnalisés.

Quel est le "vrai" coût de l'utilisation de la réflexion?

Vaut-il la peine que les types fréquemment réfléchis aient une réflexion mise en cache, comme notre propre code objet DAL pré-LINQ sur toutes les propriétés des définitions de table?

L'encombrement de la mémoire cache serait-il supérieur à l'utilisation du processeur de réflexion?

70
Tom Anderson

La réflexion nécessite le chargement puis le traitement d'une grande quantité de métadonnées de type. Cela peut entraîner une surcharge de mémoire plus importante et une exécution plus lente. Selon cet article la modification de propriété est environ 2.5x-3x plus lente et l'invocation de méthode est 3.5x-4x plus lente.

Voici un excellent article MSDN décrivant comment accélérer la réflexion et où se trouvent les frais généraux. Je recommande fortement la lecture si vous voulez en savoir plus.

Il y a aussi un élément de complexité que la réflexion peut ajouter au code qui le rend sensiblement plus déroutant et donc difficile à travailler. Certaines personnes, comme Scott Hanselman croient qu'en utilisant la réflexion, vous faites souvent plus de problèmes que vous n'en résolvez. C'est particulièrement le cas si vos équipes sont principalement des développeurs juniors.

Vous feriez mieux de regarder dans le DLR (Dynamic Language Runtime) si vous avez besoin de beaucoup de comportement dynamique. Avec les nouvelles modifications apportées dans .NET 4.0, vous voudrez peut-être voir si vous pouvez en incorporer une partie dans votre solution. La prise en charge supplémentaire de la dynamique à partir de VB et C # rendent l'utilisation du code dynamique très élégante et la création assez simple de vos propres objets dynamiques.

Bonne chance.

EDIT: J'ai fait un peu plus de fouille sur le site de Scott et j'ai trouvé cela podcast sur la réflexion. Je ne l'ai pas écouté mais cela pourrait valoir la peine.

56
smaclell

Il y a beaucoup de choses que vous pouvez faire pour accélérer la réflexion. Par exemple, si vous faites beaucoup d'accès aux propriétés, alors HyperDescriptor peut être utile.

Si vous faites beaucoup d'appels de méthodes, vous pouvez mettre en cache les méthodes des délégués typés en utilisant Delegate.CreateDelegate - ceci effectue ensuite la vérification de type, etc. une seule fois (pendant CreateDelegate).

Si vous faites beaucoup de construction d'objets, alors Delegate.CreateDelegate n'aidera pas (vous ne pouvez pas l'utiliser sur un constructeur) - mais (en 3.5) Expression peut être utilisé pour cela, en compilant à nouveau en un délégué typé.

Alors oui: la réflexion est lente, mais vous pouvez l'optimiser sans trop de douleur.

17
Marc Gravell

Merci pour les excellents liens et les excellents commentaires, en particulier de la part des Jr Devs, qui ont frappé juste sur l'argent.

Pour nous, il est plus facile pour nos développeurs juniors de le faire:

[TableName("Table")]
public class SomeDal : BaseDal
{
    [FieldName("Field")]
    public string Field
}

plutôt que quelques impélémentations plus importantes de DAL. Cela accélère leur construction des objets DAL, tout en masquant tous les rouages ​​internes pour les développeurs seniors.

Dommage que LINQ ne soit pas sorti plus tôt, j'ai l'impression que parfois nous en avons écrit la moitié.

2
Tom Anderson

Un grand pouvoir implique de grandes responsabilités.

Comme vous le dites, la réflexion a des coûts qui lui sont associés, et selon la quantité de réflexion que vous faites, elle peut ralentir considérablement l'application.

L'un des endroits les plus appropriés pour l'utiliser est l'IoC (Inversion of Control) car, selon la taille de votre application, aurait probablement plus d'avantages qu'improbable.

2
Llyle

Une chose qui peut parfois vous mordre lorsque vous utilisez la réflexion n'est pas de mettre à jour les appels en utilisant la réflexion lors de la refactorisation. Des outils tels que resharper vous inviteront à mettre à jour les commentaires et les chaînes lorsque vous modifiez un nom de méthode, de sorte que vous pouvez intercepter la plupart de cette façon, mais lorsque vous appelez des méthodes qui ont été générées dynamiquement ou que le nom de la méthode a été généré dynamiquement, vous pouvez manquer quelque chose.

La seule solution est une bonne documentation et des tests unitaires approfondis.

0
jonnii