Как стать автором
Обновить

Комментарии 19

А отчего про JNA ни слова? В следующей части будет?
Да, вторая часть как раз с JNA начинается
И вообще Java — безопасный язык.
дополню:
И вообще Java — безопасный, но тормозной язык.
В тексте ваш комментарий уже предвосхищён: «Многие люди привыкли думать, что Java тормозит».
про javacpp во второй части тоже будет :) действительно очень интересный фреймворк, во многом превосходящий аналоги, хотя и не без подводных камней.

вообще, на мой взгляд именно для связи с C++ кодом javacpp — это лучше, что есть сейчас.
Спасибо за статью. Раз уж речь зашла о нативе, то очень хотелось бы услышать по подробней про Java Foreighn Memory API. Планируете затронуть эту тему?
да, во второй части будет немного про Panama и в том числе про Foreign Memory.

но это будет буквально пара абзацев и бенчи, поэтому про эту тему рекомендую расшифровку большого доклада Вовы Иванова про всю Panama. И еще его же доклад именно про Foreign Memory (его расшифровки, к сожалению, пока нет).
О, спасибо за ссылки!
В попугаях разница устрашающая, но в абсолютных величинах это сколько? Например, по сравнению со сложением или умножением двух вещественных чисел?
Интуитивно кажется очевидным, что для масипусеньких фукнций JN(J) вызовы лучше не делать, но если фукнция выполняет какую-то более сложную работу, чем ничего, то будет ли влияние хоть сколько-то заметно? Что-нибудь простое если делать, например, суммировать элементы массива, то с какого числа элементов влияние способа вызова перестаёт иметь значение?
Хороший вопрос!

Отвечу цифрами, которые есть под рукой (из второй части доклада):

Вызов пустого натива — 119 ops/us,
Вызов натива, в котором считается 100-ое число Фибоначчи — 45 ops/us.

Т.е. видно, что просадка уже в 2.5 раза, но вызов натива здесь все еще играет большую роль.

В целом, конечно, чем больше операций в нативном методе, тем меньшую роль играет переход из Java конекста в Native (и обратно).
Есть результат для расчёта Фибонначи в Java, тем же алгоритмом, что и в нативном коде?
Догаываюсь, что в Java выходит быстрее, но интересно знать прям цифры, чтобы вопрос окончательно закрыть :)

Ещё вопрос. На какой архитектуре проводились тесты? Наверняка на х86, x64 и ARM будут различные результаты, ведь разные реализации JVM и целевая архитектура разная.
Померил.

1) если подсчет Фибоначчи оставить в Java, то получаем 509.744 ops/us (вызовов нет, а код хорошо специализировался).

2) если вынести подсчет в другой Java метод, повесить на него @CompilerControl(Mode.DONT_INLINE) (ну, чтобы немного уравнять шансы), то получаем уже всего 52 ops/us.

3) ну и вызов натива остается 45 ops/us.

Мерю все на Intel Core i7-7700 @ 3.60 GHz, т.е. на x64.
В принципе можно перемерить на арме, но что-то мне подсказывает, что там все будет хуже.

По «условию задачи» инлайн запрещён, так что пункт 1 можно исключить. Получается, что не так страшен Натив, как сперва кажется. Хотя и 20% это может быть принципиальной разницей. Видимо, по умолчанию надо пытаться избегать нативного кода, а если есть реальная необходимость использования, то там явно что-то нетривиальное и разница в скорости выполнения нативного кода будет покрывать потерю на вызове функции. А для простого кода чистый Java будет и быстрее и удобнее для программирования.
Разумеется, это в том случае, если программист умеет и в JVM и в натив примерно на одном хорошем уровне и не будет писать что-то сильно неудачое просто от того, что не может на другом языке реализовать.
Все так.

У меня в этой части посыл скорее, что не нужно думать, натив прям принесет счастье и гарантированное ускорение, на самом деле не все так просто.

Ну и да, на самом деле JNI то не так плох в плане производительности, как некоторые библиотеки, которые на нем базируются. Про это во второй части.
Первая часть на ура зашла, вторая, думаю, не хуже

скоро ли вторая часть?

Планируем завтра опубликовать
Зарегистрируйтесь на Хабре, чтобы оставить комментарий