Ранее я спросил вопрос, какой язык использовать для прототипа AI. Казалось, что консенсус заключался в том, что если я хочу, чтобы это было быстро, мне нужно использовать такой язык, как Java или C++, но этот Python / Perl / Ruby был бы хорош для бит интерфейса.
Итак, это подводит меня к другому вопросу. Насколько легко связать эти языки вместе? И какая комбинация работает лучше всего? Итак, если бы я хотел иметь программу типа CGI на Ruby, вызывающую функции C++ или Java AI, это легко сделать? Есть ли указатели на то, где я ищу информацию о подобных вещах? Или лучше было бы другое сочетание?
Мой основной опыт написания веб-приложений начался с C++ CGI, затем перешел к сервлетам Java (около 10 лет назад), а затем, после долгого перерыва в программировании, я сделал немного PHP. Но у меня не было опыта написания веб-приложения на языке сценариев, которое затем обращается к скомпилированному языку для получения важных для скорости битов. Так что любые советы будут приветствоваться!




Может быть хорошим подходом начать со сценария и вызывать язык на основе компиляции из этого сценария только для более сложных нужд.
Например, неплохо работает вызов java из скрипта ruby.
require "java"
# The next line exposes Java's String as JString
include_class("java.lang.String") { |pkg, name| "J" + name }
s = JString.new("f")
Вы можете построить свою программу на одном из языков более высокого уровня, например Python или Ruby, а затем вызывать модули, скомпилированные на языке более низкого уровня, для частей, которые вам нужны. Вы можете выбрать платформу в зависимости от желаемого языка нижнего уровня.
Например, если вы хотите писать на C++ для быстрых вещей, вы можете просто использовать простой Python или Ruby и вызывать библиотеки DLL, скомпилированные на C++. Если вы хотите использовать Java, вы можете использовать Jython или один из других динамических языков на платформе Java для вызова кода Java, это проще, чем маршрут C++, потому что у вас есть общая виртуальная машина, поэтому объект Java можно использовать напрямую. в Jython или JRuby. То же самое можно сделать на платформе .Net с помощью Iron-languages и C#, хотя у вас, кажется, больше опыта работы с C++ и Java, так что это были бы лучшие варианты.
Во-первых, мета-комментарий: я настоятельно рекомендую кодировать все это на языке высокого уровня, профилировать как сумасшедший и оптимизировать только там, где профилирование показывает, что это необходимо. Сначала оптимизируйте алгоритм, затем код, а затем подумайте о внедрении тяжелого железа. Наличие оптимального алгоритма и чистого кода значительно упростит задачу, когда / если вам нужно переопределить на языке более низкого уровня.
Говоря о Python, IronPython / C#, вероятно, самый простой путь оптимизации.
CPython с C++ выполнимо, но я считаю, что C намного проще обрабатывать (но не все так просто, будучи C). Два инструмента, которые облегчают это, - Cython / пирекс (для C) и шкура (для C++). Они компилируют Python в C / C++, и оттуда вы можете без особых усилий получить доступ к библиотекам C / C++.
Я никогда не использовал jython, но слышал, что путь оптимизации jython / Java не так уж и плох.
Boost.Python предоставляет простой способ превратить код C++ в модули Python. Он довольно зрелый и, по моему опыту, хорошо работает.
Например, неизбежный Hello World ...
char const* greet()
{
return "hello, world";
}
можно открыть для Python, написав оболочку Boost.Python:
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("greet", greet);
}
Вот и все. Были сделаны. Теперь мы можем создать это как общую библиотеку. Получившаяся DLL теперь видна Python. Вот пример сеанса Python:
>>> import hello_ext
>>> print hello.greet()
hello, world
(пример взят с boost.org)
Я согласен с идеей кодирования сначала на языке высокого уровня, таком как Python, профилирование, а затем реализация любого кода, который требует ускорения, на C / C++ и его упаковка для использования на языке высокого уровня.
В качестве альтернативы boost я хотел бы предложить SWIG для создания вызываемого кода Python из C. Его достаточно безболезненно использовать, и он будет компилировать вызываемые модули для широкого спектра языков. (Python, Ruby, Java, Lua. И многие другие) из кода C.
Процесс упаковки является полуавтоматическим, поэтому нет необходимости добавлять новые функции в базовый код C, что упрощает рабочий процесс.
Perl has several ways to use other languages. Look at the Inline:: семейство модулей на CPAN. Следуя советам других в этом вопросе, я бы написал все это на одном динамическом языке (Perl, Python, Ruby и т. д.), А затем оптимизировал бы те части, которые в этом нуждаются. С Perl и Inline :: вы можете оптимизировать на C, C++ или Java. Или вы можете посмотреть AI :: Prolog, который позволяет вам встраивать Prolog для программирования AI / Logic.
Если вы выберете Perl, появится множество ресурсов для взаимодействия с другими языками.
Встроенный :: C
Встроенный :: CPP
Встроенный :: Java
use Inline C => <<'END_C';
void greet() {
printf("Hello, world\n");
}
END_C
greet;
С Perl 6 стало еще проще импортировать подпрограммы из кода собственной библиотеки с помощью NativeCall.
use v6.c;
sub c-print ( Str() $s ){
use NativeCall;
# restrict the function to inside of this subroutine because printf is
# vararg based, and we only handle '%s' based inputs here
# it should be possible to handle more but it requires generating
# a Signature object based on the format string and then do a
# nativecast with that Signature, and a pointer to printf
sub printf ( str, str --> int32 ) is native('libc:6') {}
printf '%s', $s
}
c-print 'Hello World';
Это всего лишь простой пример, вы можете создать класс, который имеет представление Pointer, а некоторые методы должны быть кодом C из библиотеки, которую вы используете. (работает только в том случае, если первым аргументом кода C является указатель, иначе вам придется его обернуть)
Если вам нужно, чтобы имя подпрограммы / метода Perl 6 было другим, вы можете использовать модификатор свойств is symbol.
Также существуют встроенные модули для Perl 6.
У меня другая точка зрения: мне очень повезло с интеграцией C++ и Python для обработки видеоизображений в реальном времени.
Я бы сказал, что вы должны сопоставить язык с задачей для каждого модуля. Если вы отвечаете в сети, сделайте это на Python, Python может отлично справляться с сетевым трафиком. Пользовательский интерфейс: Python, люди медленные, а Python отлично подходит для пользовательских интерфейсов, использующих wxPython или PyObjC на Mac или PyGTK. Если вы занимаетесь математикой с большим количеством данных, или обрабатываете сигналы, или обрабатываете изображения ... кодируйте это на C или C++ с помощью модульных тестов, а затем используйте SWIG для создания привязки к любому языку более высокого уровня.
Я использовал библиотеки изображений в wxWidgets в моем C++, которые уже доступны для Python через wxPython, поэтому он был чрезвычайно мощным и быстрым. SCONS - это инструмент сборки (например, make), который знает, что делать с файлами swig .i.
Самый верхний уровень может быть на C или Python, у вас будет больше контроля и меньше проблем с упаковкой и развертыванием, если верхний уровень находится на C или C++ ... но потребуется очень много времени, чтобы дублировать то, что вам дает Py2EXE или Py2App в Windows или Mac (или зависнуть в Linux).
Наслаждайтесь мощью гибридного программирования! (Я называю использование нескольких языков тесно связанным образом «гибридным», но это просто моя причуда.)
Если проблемная область сложна (а проблемы с ИИ часто бывают сложными), я бы сначала выбрал язык, который является выразительным или подходящим для этой области, а затем беспокоился бы о его ускорении. Например, в Ruby есть примитивы метапрограммирования (способность легко проверять и изменять запущенную программу), которые могут очень легко / интересно реализовать определенные типы алгоритмов.
Если вы реализуете это таким образом, а затем вам потребуется ускорить его, тогда вы можете использовать тестирование / профилирование, чтобы найти узкое место и либо ссылку на скомпилированный язык для этого, либо оптимизировать алгоритм. По моему опыту, наибольший прирост производительности достигается за счет настройки алгоритма, а не за счет использования другого языка реализации.
Пару лет назад Овидий сказал мне, что AI :: PRolog слишком медленный для промышленного использования. Я хотел использовать его для проекта, и он меня отговорил :)