So che "attraversare i confini" quando si effettua una chiamata JNI in Java è lento.
Tuttavia, voglio sapere cos'è che lo rallenta? Cosa fa l'implementazione jvm sottostante quando effettua una chiamata JNI che la rende così lenta?
So che "attraversare i confini" quando si effettua una chiamata JNI in Java è lento.
Tuttavia, voglio sapere cos'è che lo rallenta? Cosa fa l'implementazione jvm sottostante quando effettua una chiamata JNI che la rende così lenta?
Risposte:
Innanzitutto, vale la pena notare che per "lento" stiamo parlando di qualcosa che può richiedere decine di nanosecondi. Per banali metodi nativi, nel 2010 ho misurato le chiamate a una media di 40 ns sul mio desktop di Windows e 11 ns sul mio desktop di Mac. A meno che tu non faccia molte chiamate, non te ne accorgerai.
Detto questo, chiamare un metodo nativo può essere più lento rispetto a una normale chiamata al metodo Java. Le cause includono:
Qualche discussione aggiuntiva, forse datata, può essere trovata in "Prestazioni della piattaforma Java: strategie e tattiche", 2000, di Steve Wilson e Jeff Kesselman, nella sezione "9.2: Esame dei costi JNI". Si trova a circa un terzo di questa pagina , fornita nel commento di @Philip di seguito.
Il documento IBM DeveloperWorks 2009 "Best practice per l'utilizzo di Java Native Interface" fornisce alcuni suggerimenti per evitare insidie sulle prestazioni con JNI.
sun.misc.Unsafe
e molte altre cose come System.currentTimeMillis/nanoTime
sono gestite tramite "magia" dalla JVM. Non sono JNI e non hanno affatto file .c / .h adeguati, a parte l'impl JVM stesso. L'approccio non può essere seguito se non stai scrivendo / hackerando la JVM.
Vale la pena ricordare che non tutti i metodi Java contrassegnati con native
sono "lenti". Alcuni di essi sono intrinseci che li rendono estremamente veloci. Per controllare quali sono intrinseci e quelli che non lo sono, si può cercare do_intrinsic
in vmSymbols.hpp .
Fondamentalmente la JVM costruisce in modo interpretativo i parametri C per ogni chiamata JNI e il codice non è ottimizzato.
Ci sono molti altri dettagli delineati in questo documento
Se sei interessato al benchmarking di JNI rispetto al codice nativo, questo progetto ha un codice per l'esecuzione di benchmark.