J'entends constamment à quel point la réflexion est mauvaise à utiliser. Bien que j'évite généralement la réflexion et que je trouve rarement des situations où il est impossible de résoudre mon problème sans cela, je me demandais ...
Pour ceux qui ont utilisé la réflexion dans les applications, avez-vous mesuré les performances et est-ce vraiment si mauvais?
c#
.net
performance
reflection
Dan Herbert
la source
la source
Réponses:
C'est. Mais cela dépend de ce que vous essayez de faire.
J'utilise la réflexion pour charger dynamiquement des assemblages (plugins) et sa "pénalité" de performance n'est pas un problème, car l'opération est quelque chose que je fais lors du démarrage de l'application.
Cependant, si vous réfléchissez à l'intérieur d'une série de boucles imbriquées avec des appels de réflexion sur chacune, je dirais que vous devriez revoir votre code :)
Pour les opérations "quelques fois", la réflexion est parfaitement acceptable et vous ne remarquerez aucun retard ou problème. C'est un mécanisme très puissant et il est même utilisé par .NET, donc je ne vois pas pourquoi vous ne devriez pas l'essayer.
la source
Dans son exposé The Performance of Everyday Things , Jeff Richter montre qu'appeler une méthode par réflexion est environ 1000 fois plus lent que l'appeler normalement.
Conseil de Jeff: si vous devez appeler la méthode plusieurs fois, utilisez la réflexion une fois pour la trouver, puis affectez-la à un délégué , puis appelez le délégué.
la source
Les performances de réflexion dépendront de l'implémentation (les appels répétitifs doivent être mis en cache, par exemple:)
entity.GetType().GetProperty("PropName")
. Étant donné que la plupart des réflexions que je vois quotidiennement sont utilisées pour remplir des entités à partir de lecteurs de données ou d'autres structures de type référentiel, j'ai décidé de comparer les performances spécifiquement à la réflexion lorsqu'elle est utilisée pour obtenir ou définir les propriétés d'un objet.J'ai conçu un test qui je pense est juste car il met en cache tous les appels répétés et uniquement les appels SetValue ou GetValue réels. Tout le code source du test de performance se trouve dans bitbucket à l' adresse : https://bitbucket.org/grenade/accessortest . L'examen est le bienvenu et encouragé.
La conclusion à laquelle je suis arrivé est qu'il n'est pas pratique et n'apporte pas d'améliorations notables des performances pour supprimer la réflexion dans une couche d'accès aux données qui renvoie moins de 100 000 lignes à la fois lorsque l'implémentation de la réflexion est bien effectuée.
Le graphique ci-dessus montre la sortie de mon petit repère et montre que les mécanismes qui surpassent la réflexion ne le font sensiblement qu'après la barre des 100 000 cycles. La plupart des DAL ne renvoient que plusieurs centaines ou peut-être des milliers de lignes à la fois et à ces niveaux, la réflexion fonctionne très bien.
la source
Si vous n'êtes pas dans une boucle, ne vous en faites pas.
la source
Mon expérience la plus pertinente a été d'écrire du code pour comparer deux entités de données du même type dans un grand modèle d'objet en termes de propriété. Je l'ai fait fonctionner, je l'ai essayé, j'ai couru comme un chien, évidemment.
J'étais découragé, puis j'ai réalisé du jour au lendemain que sans changer la logique, je pouvais utiliser le même algorithme pour générer automatiquement des méthodes pour faire la comparaison mais accéder statiquement aux propriétés. Il n'a fallu aucun temps pour adapter le code à cette fin et j'ai eu la possibilité de faire une comparaison approfondie des entités avec du code statique qui pouvait être mis à jour en un clic sur un bouton chaque fois que le modèle d'objet changeait.
Mon point étant: dans les conversations avec des collègues depuis que j'ai plusieurs fois souligné que leur utilisation de la réflexion pourrait être de générer automatiquement du code pour compiler plutôt que d'effectuer des opérations d'exécution et cela vaut souvent la peine d'être considéré.
la source
Pas massivement. Je n'ai jamais eu de problème avec cela dans le développement de bureau, sauf si, comme le déclare Martin, vous l'utilisez dans un endroit idiot. J'ai entendu que beaucoup de gens ont des craintes totalement irrationnelles concernant ses performances dans le développement de postes de travail.
Dans le Compact Framework (dans lequel je suis habituellement), c'est à peu près un anathème et devrait être évité comme la peste dans la plupart des cas. Je peux toujours m'en tirer rarement, mais je dois être très prudent avec son application, ce qui est beaucoup moins amusant. :(
la source
C'est déjà assez grave que vous devez vous inquiéter même de la réflexion effectuée en interne par les bibliothèques .NET pour le code critique pour les performances.
L'exemple suivant est obsolète - vrai à l'époque (2008), mais il y a longtemps corrigé dans des versions CLR plus récentes. La réflexion en général reste cependant quelque peu coûteuse!
Exemple: vous ne devez jamais utiliser un membre déclaré comme «objet» dans une instruction lock (C #) / SyncLock (VB.NET) dans du code hautes performances. Pourquoi? Parce que le CLR ne peut pas verrouiller sur un type de valeur, ce qui signifie qu'il doit effectuer une vérification du type de réflexion au moment de l'exécution pour voir si votre objet est réellement un type de valeur au lieu d'un type de référence.
la source
Comme pour tout ce qui concerne la programmation, vous devez équilibrer le coût des performances avec tout avantage obtenu. La réflexion est un outil inestimable lorsqu'elle est utilisée avec soin. J'ai créé une bibliothèque de mappage O / R en C # qui a utilisé la réflexion pour faire les liaisons. Cela a très bien fonctionné. La plupart du code de réflexion n'a été exécuté qu'une seule fois, donc tout impact sur les performances était assez faible, mais les avantages étaient énormes. Si j'écrivais un nouvel algorithme de tri fandangled, je n'utiliserais probablement pas la réflexion, car elle évoluerait probablement mal.
Je comprends que je n'ai pas exactement répondu à votre question ici. Mon point est que cela n'a pas vraiment d'importance. Utilisez la réflexion le cas échéant. C'est juste une autre fonctionnalité linguistique dont vous avez besoin pour apprendre comment et quand l'utiliser.
la source
La réflexion peut avoir un impact notable sur les performances si vous l'utilisez pour la création fréquente d'objets. J'ai développé une application basée sur Composite UI Application Block qui s'appuie fortement sur la réflexion. Il y avait une dégradation notable des performances liée à la création d'objets par réflexion.
Cependant, dans la plupart des cas, l'utilisation de la réflexion ne pose aucun problème. Si votre seul besoin est d'inspecter un assemblage, je recommanderais Mono.Cecil qui est très léger et rapide
la source
La réflexion est coûteuse en raison des nombreuses vérifications que le runtime doit effectuer chaque fois que vous faites une demande pour une méthode qui correspond à une liste de paramètres. Quelque part au fond, il existe du code qui fait une boucle sur toutes les méthodes d'un type, vérifie sa visibilité, vérifie le type de retour et vérifie également le type de chaque paramètre. Tout cela coûte du temps.
Lorsque vous exécutez cette méthode en interne, il y a du code qui fait des choses comme vérifier que vous avez passé une liste de paramètres compatibles avant d'exécuter la méthode cible réelle.
Si possible, il est toujours recommandé de mettre en cache le handle de méthode si l'on veut le réutiliser continuellement à l'avenir. Comme tous les bons conseils de programmation, il est souvent judicieux d'éviter de se répéter. Dans ce cas, il serait inutile de rechercher continuellement la méthode avec certains paramètres, puis de l'exécuter à chaque fois.
Parcourez la source et regardez ce qui se fait.
la source
Comme pour tout, il s'agit d'évaluer la situation. Dans DotNetNuke, il existe un composant assez central appelé
FillObject
qui utilise la réflexion pour remplir les objets à partir des lignes de données.Il s'agit d'un scénario assez courant et il existe un article sur MSDN, Utilisation de la réflexion pour lier des objets métier aux contrôles de formulaire ASP.NET qui couvre les problèmes de performances.
Mis à part les performances, une chose que je n'aime pas à propos de la réflexion dans ce scénario particulier, c'est qu'elle tend à réduire la capacité de comprendre le code en un coup d'œil, ce qui ne me semble pas valoir la peine si vous considérez que vous perdez également la compilation sécurité temporelle par opposition aux ensembles de données fortement typés ou quelque chose comme LINQ to SQL .
la source
La réflexion ne ralentit pas considérablement les performances de votre application. Vous pourrez peut-être faire certaines choses plus rapidement en n'utilisant pas la réflexion, mais si la réflexion est le moyen le plus simple d'obtenir certaines fonctionnalités, utilisez-la. Vous pouvez toujours refactoriser votre code loin de Reflection si cela devient un problème de performance.
la source
Je pense que vous constaterez que la réponse est, cela dépend. Ce n'est pas grave si vous voulez le mettre dans votre application de liste de tâches. C'est un gros problème si vous voulez le mettre dans la bibliothèque de persistance de Facebook.
la source