Ответ 1
Во-первых, стоит отметить, что "медленно" мы говорим о чем-то, что может занять десятки наносекунд. Для тривиальных собственных методов в 2010 году я измерил вызовы в среднем 40 нс на рабочем столе Windows и 11 нс на моем рабочем столе Mac. Если вы не совершаете много звонков, вы не заметите.
Тем не менее, вызов собственного метода может быть медленнее, чем обычный вызов метода Java. Причины включают:
- Собственные методы не будут включены в JVM. Они также не будут точно составлены для этой конкретной машины - они уже скомпилированы.
- Ядро Java может быть скопировано для доступа в собственном коде и позже скопировано обратно. Стоимость может быть линейной по размеру массива. Я измерил JNI-копирование массива 100 000 в среднем на 75 микросекунд на моем рабочем столе Windows и 82 микросекундах на Mac. К счастью, прямой доступ можно получить через GetPrimitiveArrayCritical или NewDirectByteBuffer.
- Если метод передан объекту или должен выполнить обратный вызов, тогда собственный метод, скорее всего, будет делать свои собственные вызовы для JVM. Доступ к Java-полям, методам и типам из собственного кода требует чего-то похожего на отражение. Подписи указываются в строках и запрашиваются из JVM. Это медленное и подверженное ошибкам.
- Строки Java - это объекты, имеющие длину и закодированные. Для доступа или создания строки может потребоваться копия O (n).
Некоторые дополнительные обсуждения, возможно, датированные, можно найти в статье "Эффективность платформы Java: стратегии и тактика", 2000, Стив Уилсон и Джефф Кессельман в разделе "9.2: Изучение расходов JNI". Это примерно на треть пути вниз эта страница, приведенная в комментарии @Philip ниже.
В документе IBM developerWorks 2009 "Рекомендации по использованию Java-интерфейса" приводятся некоторые рекомендации по предотвращению ошибок производительности с JNI.