6 votes

Mise en œuvre d'Hibernate. Payons-nous la pénalité de la réflexion ?

Il y a longtemps, je créais un mini ORM en utilisant la réflexion.

En lisant sur la réflexion, j'ai obtenu une réponse similaire à celle-ci :

Performances de Java Reflection

Ce qui est tout à fait logique et je quitte mon mini orm et aiguise mes touches CTRL+C, CTRL+V ( la librairie était destinée à éviter de devoir réécrire encore et encore les mêmes snippets pour différentes tables dans une application web sur laquelle je travaillais )

Des années plus tard, pour une raison dont je ne me souviens pas maintenant (et dont je ne veux pas me souvenir), je lisais (ou essayais de...) le code source d'Hibernate, car je voulais savoir s'ils utilisaient la POA pour générer du code à la volée et éviter la pénalité de réflexion, mais à ma grande surprise, tout ce que je voyais était de la pure réflexion.

Est-ce que cela signifie que le framework ORM le plus accepté, a fait exactement ce que des années auparavant m'ont découragé de poursuivre mes efforts naïfs ? :")

Ma question est la suivante : quelqu'un peut-il confirmer ma compréhension de l'implémentation d'Hibernate ? Génère-t-elle du bytecode à la volée pour améliorer les performances ? Ou est-ce que nous (lorsque nous l'utilisons) payons toujours la pénalité de réflexion (qui d'ailleurs, si la différence est de quelques ms, aucun d'entre nous ne l'a remarqué ni ne s'en est plaint).

Payons-nous la pénalité de réflexion ? Si c'est le cas, je pense que c'est ça vaut le coup ! !!

Regards.

9voto

mP. Points 7516

Hibernate instrumente vos modèles pour qu'ils soient compatibles avec Hibernate.

Le coût de l'utilisation de Reflection varie. La recherche constante d'une méthode pour une classe particulière est particulièrement coûteuse. L'exécution d'une méthode par réflexion en utilisant une copie en cache n'est pas beaucoup plus lente. Si l'on considère les tâches que l'API de réflexion doit accomplir pour invoquer la méthode, on comprend que chaque partie est lente et consomme des cycles de processeur.

Trouver une méthode

  • Visiter chaque méthode d'une classe particulière
  • Testez la visibilité de chaque méthode, sa signature, etc.
  • Générer le bytecode pour trouvé método.

Si l'on tient compte du nombre de méthodes dans une classe typique et du fait que certaines de ces opérations ne sont pas triviales, il est évident que cela peut être coûteux.

L'appel de la méthode.

Chaque méthode réfléchie se résume à un bout de code octet qui invoque la méthode cible avec un peu de texte passe-partout pour correspondre à l'interface de réflexion. Avant de pouvoir le faire, il doit effectuer quelques vérifications afin de pouvoir se plaindre avec des messages agréables plutôt que de laisser le runtime lancer des ClassCastException et autres exceptions similaires.

  • Si une méthode d'instance vérifie que l'instance passée n'est pas nulle et qu'elle est du bon type.
  • Vérifiez que le paramètre des arguments comprend la bonne quantité et le bon type de paramètres.
  • Exécuter la méthode à l'intérieur d'un try catch. Dans le catch, lancez l'ITE, etc.

Tous ces extras ajoutent un certain coût - pas beaucoup, mais cela ralentit les choses.

Coûts d'exécution

En général, mettre en cache des méthodes et les invoquer n'est pas coûteux mais un peu plus lent. L'API de réflexion elle-même tente de mettre en cache les méthodes et les classes mais trouver la bonne méthode et ainsi de suite est toujours une opération lente.

9voto

Pete Points 13373

Je pense que la chose importante à retenir est le coût relatif dans l'application globale. La réflexion est-elle plus lente que la création normale d'objets ? Oui. La réflexion s'est améliorée et est devenue plus rapide ? Oui. Mais ces points ne sont pas très importants si l'on compare le coût de la réflexion à celui de l'utilisation de la base de données, ce que fait Hibernate - le coût devient complètement négligeable et je dirais que nous ne payons pas le prix.

5voto

Peter Lawrey Points 229686

Le coût de la persistance et de la récupération est plusieurs fois supérieur au coût de la réflexion. L'accès à un enregistrement d'une base de données peut prendre de 1 à 10 ms, alors que la construction d'un objet par réflexion peut prendre de 0,001 à 0,01 ms.

1voto

RKitson Points 1502

NHibernate ne met-il pas en cache les informations sur les classes recueillies par réflexion afin que vous ne payiez la pénalité que la première fois ?

0voto

Teter28 Points 484

Vous payez vraiment la pénalité de réflexion en utilisant NHibernate mais son extensibilité vous permet d'éviter 90% d'entre elles si vous fournissez toutes les implémentations de réflexion optimisées via NHibernate.Bytecode.IBytecodeProvider.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X