web-dev-qa-db-fra.com

Qu'est-ce qui ralentit les appels JNI?

Je sais que "franchir les limites" lors d’un appel JNI Java est lent.

Cependant, je veux savoir quoi est-ce qui le ralentit? Que fait l'implémentation JVM sous-jacente lors d'un appel JNI qui le ralentit?

183
pdeva

Premièrement, il convient de noter que par "lent", nous parlons de quelque chose qui peut prendre des dizaines de nanosecondes. Pour les méthodes natives triviales, j'ai mesuré en 2010 les appels à une moyenne de 40 ns sur mon bureau Windows et de 11 ns sur mon bureau Mac. Sauf si vous passez de nombreux appels , vous ne le remarquerez pas.

Cela dit, appeler une méthode native peut être plus lent que de faire un appel de méthode normal Java. Les causes incluent:

  • Les méthodes natives ne seront pas insérées par la machine virtuelle Java. Ils ne seront pas non plus compilés juste à temps pour cette machine spécifique - ils sont déjà compilés.
  • Un tableau Java peut être copié pour un accès en code natif, puis copié ultérieurement. Le coût peut être linéaire dans la taille du tableau. J'ai mesuré JNI en copiant un tableau de 100 000 unités en moyenne environ 75 microsecondes sur mon bureau Windows et 82 microsecondes sur Mac. Heureusement, un accès direct peut être obtenu via GetPrimitiveArrayCritical ou NewDirectByteBuffer .
  • Si un objet est transmis à la méthode ou doit être rappelé, la méthode native effectuera probablement ses propres appels vers la machine virtuelle Java. L'accès à Java champs, méthodes et types à partir du code natif nécessite quelque chose de similaire à la réflexion. Les signatures sont spécifiées dans des chaînes et interrogées à partir de la machine virtuelle Java. C'est à la fois lent et sujet à l'erreur .
  • Les chaînes Java sont des objets, ont une longueur et sont codées. L'accès ou la création d'une chaîne peut nécessiter une copie O(n).

Des informations supplémentaires, éventuellement datées, sont disponibles dans "Performances de la plate-forme Java: stratégies et tactiques", 2000, de Steve Wilson et Jeff Kesselman, dans la section "9.2: Examen des coûts JNI". C'est à peu près au tiers de la descente cette page , fournie dans le commentaire de @Philip ci-dessous.

Le document IBM developerWorks 2009 "Meilleures pratiques pour l’utilisation de Java Native Interface" fournit des suggestions sur la manière d’éviter les pièges en matière de performances avec JNI.

166
Andy Thomas

Il est à noter que toutes les Java marquées native ne sont pas "lentes". Certaines d'entre elles sont intrinsèques , ce qui les rend extrêmement rapides. vérifiez lesquels sont intrinsèques et lesquels ne le sont pas, vous pouvez rechercher do_intrinsic à vmSymbols.hpp .

23
Tema

Fondamentalement, la machine virtuelle Java construit interprétativement les paramètres C pour chaque appel JNI et le code n'est pas optimisé.

Il y a beaucoup plus de détails décrits dans ce document

Si vous êtes intéressé par l'analyse comparative de JNI par rapport au code natif ce projet a du code pour l'exécution de tests de performance.

22
dmck