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.Unsafee molte altre cose come System.currentTimeMillis/nanoTimesono 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 nativesono "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_intrinsicin 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.