Выбор языка сценариев для начального исполнения
У меня есть небольшое легкое приложение, которое используется как часть более крупного решения. В настоящее время он написан на C, но я хочу переписать его, используя кроссплатформенный язык сценариев. Решение должно работать в Windows, Linux, Solaris, AIX и HP-UX.
Существующее приложение C работает нормально, но я хочу иметь единый скрипт, который я могу поддерживать для всех платформ. В то же время я не хочу терять производительность, но хочу потерять ее.
Стоимость запуска скрипта очень важна. Этот сценарий может вызываться где угодно от каждой минуты до много раз в секунду. Как следствие, сохранение памяти и времени запуска очень важны.
В общем, я ищу лучшие скриптовые языки, которые:
- Кроссплатформенный.
- Возможность разбора XML и HTTP-сообщений.
- Недостаточно памяти и время запуска.
Возможные варианты включают, но не ограничиваются: bash/ksh + curl, Perl, Python и Ruby. Что бы вы порекомендовали для этого типа сценария?
13 ответов
Из-за вашего требования к быстрому времени запуска и частоте вызова более 1 Гц, я бы порекомендовал либо остаться с C и выяснить, как сделать его переносимым (не всегда так просто, как несколько ifdefs), либо изучить возможность превратить его в сервисный демон, который всегда работает. Конечно это зависит от того, как
Python может иметь меньшее время запуска, если вы скомпилируете модуль и запустите файл.pyc, но он все еще считается медленным. Perl, по моему опыту, в самом быстром из скриптовых языков, так что вам может повезти с демоном perl.
Вы также можете посмотреть на кроссплатформенные фреймворки, такие как gtk, wxWidgets и Qt. Хотя они предназначены для графических интерфейсов, они имеют низкоуровневые кроссплатформенные типы данных и сетевые библиотеки, которые могут упростить работу с быстрым приложением на основе Си.
Lua - это язык сценариев, который соответствует вашим критериям. Это, безусловно, самый быстрый и самый низкий доступный язык сценариев памяти.
"Вызывается в любом месте от каждой минуты до много раз в секунду. Как следствие, важно сохранять память и время запуска на низком уровне".
Это совсем не похоже на сценарий для меня.
Это звучит как сервер, обрабатывающий запросы, которые поступают от каждой минуты до нескольких раз в секунду.
Если это сервер, обрабатывающий запросы, время запуска не означает столько же, сколько отзывчивость. В этом случае Python может работать хорошо и при этом поддерживать производительность.
Вместо перезапуска вы просто обрабатываете другой запрос. Вы можете сохранить столько состояния, сколько вам нужно для оптимизации производительности.
Когда написано правильно, C должен быть независимым от платформы и потребуется только перекомпиляция для этих различных платформ. Возможно, вам придется перепрыгнуть через некоторые циклы #ifdef для заголовков (не все системы используют одинаковые заголовки), но большинство обычных (не win32 API) вызовов очень переносимы. Что касается веб-доступа (который, я полагаю, вам нужен, когда вы упоминаете bash+curl), вы можете взглянуть на libcurl, он доступен для всех платформ, о которых вы упомянули, и не должен быть таким сложным для работы.
Учитывая время выполнения и затраты памяти, я сомневаюсь, что вы могли бы работать быстрее, чем правильно написанный C, на любом языке сценариев, поскольку вы потеряли бы хотя бы некоторое время на интерпретацию сценария...
Я согласен с Lua: он является сверхпортативным, имеет XML-библиотеки, как собственные, так и связывающие библиотеки C, такие как Expat, имеет хорошую библиотеку сокетов (LuaSocket) плюс, для сложных вещей, некоторые привязки cURL и хорошо известен очень легкий (часто встроенный в устройства с малым объемом памяти), очень быстрый (один из самых быстрых языков сценариев) и мощный. И очень легко кодировать!
Он написан на чистом Ansi C, и многие люди утверждают, что он имеет один из лучших API связывания C (вызов подпрограмм C из Lua, вызов кода Lua из C...).
Как и другие предлагали, демонизация вашего сценария может быть хорошей идеей; это уменьшит время запуска практически до нуля. Либо есть небольшая оболочка C, которая подключается к вашему демону и передает запрос туда и обратно, либо даемон обрабатывает запросы напрямую.
Не ясно, предназначено ли это для обработки HTTP-запросов; В этом случае у Perl есть хороший модуль HTTP-сервера, привязка к нескольким различным синтаксическим анализаторам XML на основе C и потрясающая быстрая поддержка строк. (Если вы не хотите демонизировать, у него есть хороший, полнофункциональный модуль CGI; если у вас есть полный контроль над сервером, на котором он работает, вы также можете использовать mod_perl для реализации вашего скрипта в качестве обработчика Apache.) Строки Ruby немного медленнее, но для него есть несколько действительно хороших фоновых инструментов. Боюсь, я не так хорошо знаком с Python, поэтому не могу дать никаких рекомендаций по этому поводу.
В целом, однако, я не думаю, что вы ограничены во времени запуска, как вы думаете. Если скрипт действительно вызывается несколько раз в секунду, любой приличный интерпретатор в любой приличной операционной системе будет кэшироваться в памяти, как и исходный код вашего скрипта и его модулей. Результат: время запуска не будет таким плохим, как вы думаете.
Dagny:~ brent$ time perl -MCGI -e0
real 0m0.610s
user 0m0.036s
sys 0m0.022s
Dagny:~ brent$ time perl -MCGI -e0
real 0m0.026s
user 0m0.020s
sys 0m0.006s
(Параметры интерпретатора Perl загружают довольно большой модуль CGI и затем выполняют строку кода '0;'.)
Если Недостаток памяти и время запуска действительно важны, вы можете рассмотреть возможность выполнения работы, чтобы сохранить кросс-платформенность кода на C, однако я обнаружил, что это редко необходимо.
Лично я бы использовал Ruby или Python для этого типа работы, они оба очень легко делают понятный понятный код, который могут поддерживать другие (или вы можете поддерживать, не глядя на него в течение 6 месяцев). Если у вас есть контроль, я бы также предложил получить последнюю версию интерпретатора, так как в последнее время как в Ruby, так и в Python произошли заметные улучшения в производительности.
Это что-то личное. Программирование на Ruby делает меня счастливым, а код на C - нет (ни bash-скриптинг для чего-то нетривиального).
Питон это хорошо. Я бы также зашел на сайт игры "Тесты компьютерных языков":
http://shootout.alioth.debian.org/
Возможно, стоит потратить немного времени на понимание тестов (включая цифры времени запуска и использования памяти). Сравниваются многие языки, такие как Perl, Python, Lua и Ruby. Вы также можете сравнить эти языки с тестами в C.
Я согласен с другими в том, что вам, вероятно, следует попытаться сделать это приложение более портативным, а не переносить его на что-то другое, поскольку любой язык сценариев будет представлять значительные издержки с точки зрения запуска, иметь гораздо больший объем памяти и будет вероятно, будет намного медленнее.
По моему опыту, Python является наиболее эффективным из трех, затем следует Perl, а затем Ruby, причем разница между Perl и Ruby особенно велика в определенных областях. Если вы действительно хотите попробовать перенести это на язык сценариев, я бы собрал прототип на языке, который вам наиболее удобен, и посмотрим, соответствует ли он вашим требованиям. Если у вас нет предпочтений, начните с Python, поскольку его легко изучить и использовать, и если он слишком медленный с Python, Perl и Ruby, вероятно, не смогут добиться большего успеха.
Помните, что если вы выберете Python, вы также можете расширить его на C, если производительность невелика. Черт возьми, вы могли бы даже использовать часть кода, который у вас есть сейчас. Просто перекомпилируйте его и оберните, используя пирекс.
Вы также можете сделать это довольно легко в Ruby и в Perl (хотя и с некоторыми дополнительными трудностями). Не спрашивайте меня о способах сделать это все же.
Портируйте ваше приложение на Ruby. Если ваше приложение работает слишком медленно, профилируйте его и перепишите эти части на C.
Можете ли вы вместо этого иметь длительный процесс и отвечать на запросы http или rpc?
Это удовлетворяет требованиям к задержке практически в любом сценарии, но я не знаю, нарушит ли это ограничения памяти.
На первый взгляд, это звучит как излишняя инженерия, и, как правило, я рекомендую исправлять только тогда, когда что-то сломано.
У вас уже есть работающее приложение. По-видимому, вы хотите вызвать функцию из нескольких источников. Похоже, описание услуги для меня (возможно, проще в обслуживании).
Наконец, вы также упомянули, что это часть более крупного решения, тогда вы можете использовать язык, возможности более крупных решений. Из описания, которое вы дали (xml+http), кажется, что это довольно обычное приложение, которое может быть написано на любом универсальном языке (может быть, веб-контейнер в Java?).
Некоторые библиотеки могут помочь вам сделать ваш код переносимым: Boost, Qt
больше деталей может вызвать больше идей:)