Question

On m'a dit d'utiliser Reflection.Emit au lieu de PropertyInfo.GetValue / SetValue car c'est plus rapide de cette façon. Mais je ne sais pas vraiment quels éléments de Reflection.Emit et comment les utiliser pour remplacer GetValue et SetValue. Quelqu'un peut-il m'aider avec cela?

Était-ce utile?

La solution

Juste une réponse alternative; si vous voulez des performances, mais une API similaire - considérez HyperDescriptor ; ceci utilise Reflection.Emit en dessous (pour que vous n'ayez pas à le faire), mais s'expose lui-même sur l'API PropertyDescriptor . Vous pouvez donc simplement utiliser:

PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj);
props["Name"].SetValue(obj, "Fred");
DateTime dob = (DateTime)props["DateOfBirth"].GetValue(obj);

Une ligne de code pour l'activer, qui gère tout le cache, etc.

Autres conseils

Si vous récupérez / définissez la même propriété plusieurs fois, utiliser quelque chose pour construire une méthode de type sécurité sera en effet plus rapide que la réflexion. Cependant, je suggérerais d'utiliser Delegate.CreateDelegate au lieu de Reflection.Emit. Il est plus facile de bien faire les choses et toujours extrêmement vite.

Je l'ai utilisé dans mon implémentation de tampons de protocole et cela a fait une énorme différence par rapport à PropertyInfo.GetValue / SetValue . Comme d’autres l’ont dit, ne faites cela qu’après avoir prouvé que la méthode la plus simple est trop lente.

J'ai un article de blog avec plus de détails si vous décidez de descendre la route CreateDelegate .

Utiliser PropertyInfo.GetValue / SetValue

Si vous rencontrez des problèmes de performances, mettez en cache l'objet PropertyInfo (n'appelez pas à plusieurs reprises GetProperty)

Si - et seulement si - l'utilisation de la réflexion est le goulot d'étranglement des performances de votre application (comme indiqué dans un profileur), utilisez Delegate.CreateDelegate

Si - et vraiment vraiment si - vous êtes absolument certain que lire / écrire les valeurs est toujours le pire goulot d'étranglement, il est temps de commencer à vous familiariser avec le monde amusant de la génération d'IL en mode d'exécution.

Je doute vraiment que cela en vaille la peine, chacun de ces niveaux augmentant davantage la complexité du code qu'ils n'améliorant les performances, ne le faites que si vous devez le faire.

Et si l'accès aux propriétés à l'exécution est votre goulot d'étranglement au niveau des performances, il est probablement préférable d'utiliser un accès à la compilation (il est difficile de disposer à la fois de performances génériques et de performances extrêmement élevées en même temps).

L’objet de Reflection.Emit est complètement différent de celui de PropertyInfo.Get / SetValue. Via Reflection.Emit, vous pouvez directement émettre du code IL, par exemple dans des assemblys compilés dynamiquement, et exécuter ce code. Bien entendu, ce code pourrait accéder à vos propriétés.

Je doute sérieusement que cela sera beaucoup plus rapide que d'utiliser PropertyInfo à la fin, et ce n'est pas fait pour cela non plus. Vous pouvez utiliser Reflection.Emit comme générateur de code pour un petit compilateur, par exemple.

Utilisation de Reflection.Emit semble un peu trop "intelligent", ainsi qu’une optimisation prématurée. Si vous profilez votre application et constatez que le goulet d'étranglement est dû à GetValue / SetValue Reflection, vous pouvez envisager de l'optimiser, mais probablement même pas à ce moment-là ...

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