Подтвердить что ты не робот

Переписать код C на Java или использовать JNI?

В настоящее время я разрабатываю проект, написанный на Java. У нас есть куча алгоритмов, написанных на C/С++ (не менее пары сотен), которые необходимо включить в наш проект. Наши два варианта - использовать JNI для вызова этого кода или переписать все алгоритмы в Java.

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

В этой ситуации JNI упростит эту задачу? Или это вызовет больше головной боли, чем переписывание кода на Java?


EDIT # 1: Связанный с нами вопрос - Полезность JNI


РЕДАКТИРОВАТЬ № 2: FYI. Наш проект Java не должен быть каким-либо переносимым. Это может исключить один из недостатков JNI в том, что он якобы снижает переносимость.

4b9b3361

Ответ 1

Простым ответом является то, что если код будет называться много, а производительность имеет значение, то преобразуйте его в Java.

Более сложные ответы:

  • если библиотека, легко завернутая в JNI, затем переходите к JNI
  • если тесты, которые у вас есть для кода C/С++, легко преобразуются в Java, затем перейдите к порту

Я бы сделал следующее:

  • возьмите один из алгоритмов и оберните его в JNI
  • взять тот же алгоритм и преобразовать его в Java
  • Посмотрите, что больше больно делать
  • если скорость имеет значение, тогда профиль обеих версий и посмотреть, какая из них приемлема.

Ответ 2

Я думаю, что ответ кроется в сумме связи между вызывающим Java-кодом и вызываемым кодом C/С++ и тем уровнем усилий, который повлечет за собой переписывание. Если ваш C-код занимает несколько целых чисел, выполняет некоторые волосатые вычисления и возвращает другой int. Используйте JNI. Если много сложного назад и вперед, но алгоритмы достаточно просты, перепишите их. Линией сбоя является соединение JNI. Если это будет сложно, вы можете написать более код интерфейса JNI, чем код алгоритма для перезаписи.

Ответ 3

Если "алгоритмы" хорошо упакованы, возможно, возможно создать некоторый автоматический код клея через JNI? Это уменьшило бы риск ошибок (создание сотен отдельных компонентов вручную звучит рискованно) и сделать стоимость, не зависящую от количества алгоритмов, добавить больше или меньше.

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

Какие требования ввода-вывода выполняются алгоритмами в отношении остальной части проекта? Если они довольно слабо связаны, возможно, можно будет запускать их как самостоятельные отдельные программы, вызываться в качестве подпроцессов с Java и с использованием, например, stdio для обмена данными?

Ответ 4

Я думаю, вы обнаружите, что использование JNI не так сложно, как кажется перед погружением. Существуют некоторые важные компромиссы и ограничения, но в целом JNI работает хорошо и достаточно легко использовать, как вы планируете.

Как утверждают другие, лучшим примером для JNI является:

  • Сложный собственный код (бонусные баллы, если этот код уже зарекомендовал себя очень надежно)
  • Минимальная обратная связь между Java и собственным кодом (вы хотите минимизировать поездки по слою JNI).
  • Достаточно простой интерфейс вызова к собственному коду (или обратно к Java, если вы являетесь внутренним кодом, необходимо использовать объекты/методы Java)

Определенно возможно автоматизировать или псевдоавтоматизировать создание уровня JNI для достаточно структурированного набора собственных компонентов. Это было бы хорошо, если количество компонентов для упаковки велико.

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

Переписывание большого количества алгоритмов C/С++ в Java представляется мне гораздо более рискованным, чем использование JNI. Разумеется, без знания деталей трудно оценить, но есть тонкие различия между технологиями, которые я могу себе представить, влияющими на фактическую реализацию алгоритма, не говоря уже о простом инженерном усилии и риске ошибки.

Окончательное рассмотрение - будущая жизнь этих алгоритмов или связанных компонентов. Является ли набор алгоритмов более или менее полным, или вы продолжаете добавлять? В любом случае, существует ли серьезное обоснование поддержки и/или будущего развития для поддержки одной технологии над другой? Например, если все остальное находится в Java, и все новые алгоритмы будут в Java, и почти каждый из команды почти всегда кодирует в Java, переопределение на Java начинает выглядеть более привлекательным долгосрочным.

Однако даже с учетом сказанного, рабочие козыри последовательны. Для большого количества хорошо функционирующих родных компонентов я все же был бы склонен начинать с JNI, даже если вы собираетесь переходить на Java на долгосрочную перспективу.

Ответ 5

Я бы серьезно подумал о том, чтобы пойти на JNI, особенно если вы можете свести к минимуму количество межъязыковых интерфейсов.

Если, например, существует целый стек из C-функций, все из которых имеют одинаковые входы и выходы, но просто выполняют разную работу с входами, оберните их в одну обертку JNI с дополнительным параметром, чтобы указать, какой конкретный алгоритм для использования.

Ответ 6

Если вы планируете писать будущие проекты на Java, в отличие от C/С++. Теперь я бы укусил пулю и переносил код на java. Чем дольше вы ждете, тем хуже станет. JNI звучит привлекательно в этом случае, но тогда у вас будет проблема с кем-то, кто должен поддерживать код С++, когда все остальные будут в интересных новых Java-проектах.

Если это одноразовый Java-проект, то почему вы пишете его на Java?

Ответ 7

Мост между C и Java стоит дорого, поэтому, если вам нужно передавать много данных назад и вперед, выигрыш в вызове C над JNI отсутствует.

Я видел, что JNA упоминается как разумная альтернатива JNI с гораздо меньшей болью, чтобы вызвать методы в DLL/разделяемой библиотеке из Java как отражение. Я еще не пробовал.

Возможно, вы захотите рассмотреть вопрос о компиляции вашего C-кода в виде бинарного файла Linux MIPS, который может быть интерпретирован на Java. Достаточно быстро, немного сложно настроить правильно. См. http://nestedvm.ibex.org/

Также вы можете использовать llvm backend для gcc для компиляции байт-кодов lowlevel, которые затем могут быть интерпретированы на Java. Это также подход, применяемый к iPhone SDK afaik на Mac OS X. http://llvm.org/

Ответ 8

Прочитайте сообщение joel receint на "" Уплата вашего технического долга", затем переходите к нему и конвертируйте его сейчас, а не выплачивайте проценты за следующую пару лет, а затем погасить.

Возможно, переупакованные библиотеки могут быть полезны и в других местах. Если они полезны и достаточно сложны, чтобы заставить вас рассмотреть вопрос о сохранении их на C, они должны обладать еще большим использованием после того, как они были хорошо упакованы в многоразовые, легко распространяемые и понятные классы.

Ответ 9

Я был в этой ситуации. Я предлагаю вам привыкнуть к использованию многопоточных структур данных, доступных на Java. На этом этапе вам больше не захочется возвращаться к вашим структурам данных на С++.

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

Когда вы сидите в коде на C/С++, вы думаете, что хотите продолжать его использовать. Вы думаете обо всей любви, которую вы вложили в нее. Через несколько лет вы поймете, что, держась за нее и используя JNI, вы создали монстра. Каждый раз, когда вы получаете крах процесса, вы будете сожалеть об использовании JNI. После исправления сбоя процесса кто-то захочет изменить алгоритм на С++, и вы захотите его отключить. У них будет такое удобное оправдание, как "Я еще не привык к Java".

Взгляните на неизменные структуры данных в Java. Даже не думайте о скорости, которую выполняют эти старые алгоритмы C/С++. Я обнаружил, что мой новый код намного превосходит мой старый код на C/С++.

Напишите модульные тесты. Используйте NetBeans.

С уважением,

-Stosh

Ответ 10

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

Ответ 11

Если это только для Windows, и они уже находятся в DLL, возможно, JNA будет полезен. (если производительность для вызовов функций через JNA не так уж плоха)