Связывание языков
Я спросил вопрос о том, какой язык использовать для прототипа AI. Консенсус, казалось, заключался в том, что, если я хочу, чтобы он был быстрым, мне нужно использовать язык, подобный Java или С++, но этот Python/Perl/Ruby был бы хорош для бит интерфейса.
Итак, это приводит меня к другому вопросу. Насколько легко связать эти языки вместе? И какая комбинация работает лучше всего? Итак, если бы я хотел иметь Ruby CGI-тип, вызывающий функции С++ или Java AI, это легко сделать? Любые указатели на то, где я ищу информацию о том, как это сделать? Или лучше будет другая комбинация?
Мой основной опыт написания веб-приложений начался с С++ CGI, а затем перешел к сервлетам Java (около 10 лет назад), а затем после долгого отставания от программирования я сделал несколько PHP. Но у меня не было опыта написания веб-приложения на языке сценариев, который затем вызывается на скомпилированный язык для критически важных бит. Поэтому любые советы будут приветствоваться!
Ответы
Ответ 1
Boost.Python предоставляет простой способ превратить код С++ в модули 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)
Ответ 2
Во-первых, мета-комментарий: я бы очень рекомендовал кодировать всю вещь на языке высокого уровня, профилировать, как сумасшедший, и оптимизировать только там, где профилирование показывает, что это необходимо. Сначала оптимизируйте алгоритм, затем код, а затем подумайте о вводе тяжелого железа. Наличие оптимального алгоритма и чистого кода упростит работу, если вам нужно переопределить язык более низкого уровня.
Говоря о Python, IronPython/С#, вероятно, самый простой путь оптимизации.
CPython с С++ выполним, но я нахожу C намного легче обрабатывать (но не все так просто, будучи C). Два инструмента, которые облегчают это: cython/pyrex (для C) и shedskin (для С++). Они скомпилируют Python в C/С++, и оттуда вы можете получить доступ к C/С++-библиотекам без особого шума.
Я никогда не использовал jython, но я слышал, что путь оптимизации jython/Java не так уж плох.
Ответ 3
Я согласен с идеей кодирования сначала на языке высокого уровня, таком как Python, Profiling, а затем реализует любой код, который нуждается в ускорении в C/С++ и обертывает его для использования на языке высокого уровня.
В качестве альтернативы boost я хотел бы предложить SWIG для создания кода вызова Python с C. Его разумная безболезненность в использовании и компиляция вызываемых модулей для широкого спектра языков. (Python, Ruby, Java, Lua., Чтобы назвать несколько) из кода C.
Процесс упаковки является полуавтоматизированным, поэтому нет необходимости добавлять новые функции в базовый код C, делая более плавный поток работы.
Ответ 4
Если вы выберете Perl, есть много ресурсов для взаимодействия с другими языками.
Inline:: C
Inline:: CPP
Inline:: Java
Из Inline:: C-Cookbook:
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';
Это простой пример, вы можете создать класс, который имеет представление указателя, а некоторые из методов - код C из библиотеки, которую вы используете. (работает только в том случае, если первым аргументом кода C является указатель, иначе вам придется его обернуть)
Если вам нужно, чтобы имя подпрограммы/метода Perl 6 отличалось, вы можете использовать модификатор признака is symbol
.
Существуют также встроенные модули для Perl 6.
Ответ 5
Perl имеет несколько способов использования других языков. Посмотрите Inline:: семейство модулей на CPAN. Следуя советам других в этом вопросе, я бы написал все это на одном динамическом языке (Perl, Python, Ruby и т.д.), А затем оптимизировал необходимые ему биты. С Perl и Inline:: вы можете оптимизировать работу на C, С++ или Java. Или вы можете посмотреть AI::Prolog, который позволяет вставлять Prolog для программирования AI/Logic.
Ответ 6
Это может быть хороший подход к началу работы с script и вызывать язык на основе компиляции из этого script только для более сложных потребностей.
Например, вызов java из ruby script работает достаточно хорошо.
require "java"
# The next line exposes Java String as JString
include_class("java.lang.String") { |pkg, name| "J" + name }
s = JString.new("f")
Ответ 7
Вы можете создать свою программу на одном из языков более высокого уровня, например Python или Ruby, а затем вызывать модули, которые скомпилированы на языке более низкого уровня для тех частей, которые вам нужны. Вы можете выбрать платформу в зависимости от языка более низкого уровня, который вы хотите.
Например, если вы хотите сделать С++ для быстрого материала, вы можете просто использовать простой Python или Ruby и вызвать библиотеки DLL, скомпилированные на С++. Если вы хотите использовать Java, вы можете использовать Jython или один из других динамических языков на платформе Java для вызова кода Java, это проще, чем маршрут С++, потому что у вас есть общая виртуальная машина, так что объект Java можно использовать напрямую в Jython или JRuby. То же самое можно сделать и на платформе .NET с Iron-languages и С#, хотя у вас, похоже, больше опыта работы с С++ и Java, поэтому это были бы лучшие варианты.
Ответ 8
У меня другая перспектива, с большим успехом интегрировав С++ и Python для обработки видео в реальном времени в реальном времени.
Я бы сказал, что вы должны соответствовать языку для задачи для каждого модуля. Если вы отвечаете на сеть, сделайте это в Python, Python может нормально следить за сетевым трафиком. UI: Python, люди медленные, а Python отлично подходит для пользовательских интерфейсов с использованием wxPython или PyObjC на Mac или PyGTK. Если вы делаете математику с большим количеством данных или обработкой сигналов или обработкой изображений... код на C или С++ с модульными тестами, используйте SWIG, чтобы создать привязку к любому языку более высокого уровня.
Я использовал библиотеки изображений в wxWidgets на моем С++, которые уже были подвержены Python через wxPython, поэтому он был чрезвычайно мощным и быстрым. SCONS - это инструмент построения (например, make), который знает, что делать с swig.i файлами.
Самый верхний уровень может быть на C или Python, у вас будет больше контроля и меньше проблем с упаковкой и развертыванием, если верхний уровень находится на C или С++... но для повторения того, что Py2EXE или Py2App предоставляет вам Windows или Mac (или замораживает Linux.)
Наслаждайтесь мощным гибридным программированием! (Я называю использование нескольких языков жестко связанными "гибридами", но это просто мой причуда.)
Ответ 9
Если проблемная область сложная (и проблемы с ИИ часто могут быть трудными), тогда я бы выбрал язык, который является выразительным или подходит для домена сначала, а затем беспокоиться о его ускорении. Например, у Ruby есть метапрограммирующие примитивы (возможность легко исследовать и модифицировать запущенную программу), что может очень легко/интересно реализовать определенные типы алгоритмов.
Если вы реализуете его таким образом, а затем позже должны его ускорить, вы можете использовать бенчмаркинг/профилирование, чтобы найти узкое место и либо ссылку на скомпилированный язык для этого, либо оптимизировать алгоритм. По моему опыту, наибольший прирост производительности - это настройка алгоритма, а не использование другого языка реализации.