Производительность Javonet - PullRequest
0 голосов
/ 27 апреля 2018

Пока что я заставил Javonet работать с вызовом .net dll. Создать код javonet было так же просто, как рекламировалось.

Однако, в моем случае, у меня есть цикл, который выполняется около 10 миллионов раз, и в этом цикле я вызываю метод dll через Javonet. Мой вопрос: поскольку я, кажется, передаю имя метода в виде строки в Javonet (основываясь на способе работы javonet), я предполагаю, что Javonet использует какое-то отражение, чтобы найти соответствующий метод dll ... но не будет Это будет медленно (когда в цикле 10 миллионов), особенно с учетом того, что мы зарегистрировали около десятка различных dll для javonet (или медленнее, чем решения, такие как jni4net и jnbridge, которые, кажется, генерируют реальные прокси, которые позволяют мне ссылаться в мой java код метод dll называет себя без передачи имени метода в виде строки?)

Кроме того, достаточно ли у Javonet «умного», чтобы скопировать весь массив (примитивов) в «память / стек Java VM», чтобы при попытке доступа к каждому элементу (очень большой массив размером около 2 ГБ) он не пытаетесь сделать JNI-вызов для каждого элемента доступа?

Наконец, в общем, есть ли теоретическая (или наблюдаемая) причина, по которой Javonet будет (существенно) быстрее / медленнее, чем jni4net или jnbridgePro в моем сценарии выше (цикл размером 10 миллионов и массивы примитивов, которые содержат приблизительно 2 ГБ) примитивных поплавков)?

1 Ответ

0 голосов
/ 27 апреля 2018

Спасибо за хороший отзыв!

Javonet не делает отражения вызовов для каждого из ваших 10 миллионов вызовов, мы сканируем типы в первый раз, но все последующие вызовы выполняются с фиксированными указателями на целевой метод.

Примечание: В настоящее время в Javonet для разработчиков Java ваше имя строкового метода по-прежнему передается стороне .NET (даже не используется в дальнейших вызовах), что может повлиять на производительность, но мы уже оптимизировали это в Javonet для разработчиков .NET. Обратитесь в службу поддержки Javonet по электронной почте, чтобы получить неофициальную сборку с этой оптимизацией, включенной в Java-версию продукта.

Если вы извлекаете массивы примитивов Javonet вернет весь массив за один вызов, так что вы сможете использовать его далее как чистый массив Java без каких-либо обращений к стороне .NET. Javonet также может возвращать смешанные массивы, где некоторые элементы являются примитивами (переведенными в java-типы), а некоторые являются классами, которые отображаются в виде NObject экземпляров в окончательном Java Object [] .

Намеренно мы предпочитаем создание JIT-оболочек и наш API стиля отражения по сравнению с предварительно сгенерированными оболочками, чтобы обеспечить максимальную гибкость использования Javonet. Таким образом, разработчики могут сами решить, как они используют целевые библиотеки, как они оптимизируют код, чтобы минимизировать трансграничные вызовы. Более того, нет необходимости устанавливать какие-либо инструменты или расширения или запускать какие-либо приложения для использования .NET DLL через Javonet. Наша цель - убедиться, что вы загрузили один файл и использовали любой код .NET из Java в течение первых 5 минут.

Подводя итог, Javonet фактически создает фиксированную оболочку на лету во время выполнения. Для удобства использования синтаксиса вы можете обернуть свой класс строго типизированными интерфейсами и направить вызовы внутри через API Javonet. После первого звонка ваш маршрут будет оптимизирован и должен выполнять в среднем девять миллионных секунды на звонок. Дайте нам знать, если у вас есть более высокие потребности, мы будем рады удовлетворить ваши требования!

Пример оболочки может выглядеть следующим образом:

class Car {
     private NObject handle;

     public Car() throws JavonetException {
         handle = Javonet.New(Car.class.getName());
     }

     public void increaseSpeed(int newSpeed) {
         handle.invoke("startEngine", newSpeed);
     }
     public void addPassenger(Passenger person) {
         handle.invoke("addPassenger", person);
     }
}
class Passenger {
     private NObject handle; 

     public Passenger(String name) {
         handle = Javonet.New(Passenger.class.getName(),name);
     }
}

Обратите внимание на приватное поле "handle". Если вы позвоните Javonet.setUsePrivateHandleField (значение bool) перед активацией Javonet. Когда вы передадите экземпляр такого класса с частным дескриптором поля Javonet в качестве аргумента любому методу .NET, Javonet будет использовать правильный экземпляр .NET.

...