Есть ли инструмент, который преобразует исходный код на Perl в исходный код на C? Любая платформа подойдет.
Как я могу преобразовать Perl в C?
Ответы (6)
Существует perlcc, который "переводит" Perl на C.
На самом деле это не компилятор Perl в C; его вывод представляет собой просто связку интерпретатора Perl и проанализированного байт-кода вашей программы.
B::C
, и B::CC
в настоящее время кажутся сломанными.
- person Alexej Magura; 10.02.2018
Канонический ответ на этот вопрос звучит так: MJD "Почему бы не перевести Perl на C? "а>.
Ответ будет в значительной степени «Нет». Perl — чрезвычайно динамичный язык. C — это язык для типов данных статического размера. Любой перевод Perl на C, скорее всего, будет в значительной степени «выполнять этот вызов подпрограммы, чтобы имитировать то, что делает Perl». Да и смысла в создании такого транслятора мало, поскольку он вряд ли будет выполнять Perl намного быстрее, чем это делает Perl.
Я написал довольно большую программу на Perl, которая создает PDF на основе HTML и запросов к базе данных, которая фактически действует как браузер. Общий объем исходного кода превышает 1 МБ. Программа оценивает HTML, создает SQL-запросы и извлекает данные, ищет изображения на диске или загружает их с HTTP-серверов, создает структуру документа, выполняет все расчеты макета и, наконец, создает PDF-файл.
Мне нужно было выяснить, как ускорить операцию несколькими способами. Исходя из этого, я утверждаю, что Perl довольно быстр, и многие задачи, быстро и успешно выполняемые в Perl, занимают много времени в C и даже в C++.
Есть 2 способа сделать Perl медленным или потребляющим память: большое количество сложных структур данных — им нужно много памяти — и большое количество вычислений. Да, вычисления в Perl действительно очень медленные. Простой термин вроде
$a = $b * $c
занимает довольно много времени в Perl, но очень быстро на любом компилируемом языке. Операнды здесь могут быть даже целыми числами, а не переменными с плавающей запятой — это медленно. Я предполагаю, что именно по этой причине Perl получил довольно плохие результаты в конкурсе языковых перестрелок [http://shootout.alioth.debian.org/] (Игра компьютерных языковых тестов).
Я обнаружил, что моя довольно большая программа — она использует много ядер Perl и дополнительных модулей CPAN — быстро запускается, несмотря на интерпретацию.
Он работает очень хорошо... пока не доходит до расчета размеров текста и координат макета. Это очень много времени. После этого я написал небольшие тестовые программы на Perl, просто выполняющие миллионы арифметических вычислений, и обнаружил, что они очень медленные.
Кроме того, я использую объектно-ориентированный подход для моделирования каждого элемента макета. Каждый объект представлен хешем — это не менее 10 КБ на объект. Если требуется распечатать большой объем данных, потребление памяти в несколько 100 МБ не является чем-то необычным для этой программы.
Итак, у меня все еще есть веская причина переместить часть расчета макета на C, используя структуры, где теперь у меня есть хэши с фиксированными ключами и целочисленная арифметика C, где теперь Perl работает медленно.
Но все остальное было сделано и протестировано быстро и работает так быстро, что я не вижу смысла что-либо менять. Я также считаю, что код на Perl гораздо удобнее писать и тестировать, чем код на C. И многие модули CPAN предоставляют решения, которые вам не нужно разрабатывать самостоятельно. Многие из них хорошо протестированы и задокументированы.
После этого довольно продолжительного обсуждения я пришел к выводу: если это будет серверная программа или программа командной строки, рассмотрите Perl. Но если эта программа должна создавать огромные структуры данных или много арифметических операций, подумайте о чем-то более быстром. Иногда это может быть Perl-программа с модулем, написанным на C.
Существуют трансляторы Perl в C, но ни один из них не идеален. В идеале вам нужен переводчик, который одновременно корректен и элегантен. Увы, у вас не может быть и того, и другого, простой код Perl не эквивалентен простому коду C, поэтому вам нужно либо иметь перевод, который не на 100% правильный, либо такой же сложный, как и сам Perl. Это привело некоторых к мысли, что вам не следует пытаться переводить Perl. Точнее было бы сказать, что нужно четко представлять, чего вы хотите добиться от перевода, а не ждать чудес.
100% Исправить легко: если ваш Perl-скрипт myperl.pl, то программа C void main(){system("perl myperl.pl")}
будет делать точно то же, что и myperl.pl; хотя это довольно бессмысленно. Компилятор perlcc
немного сложнее, но по-прежнему не дает особых преимуществ. Я не заметил, чтобы perlcc
работал быстрее, чем простой Perl. Кроме того, хотя код Perl может быть заведомо трудным для чтения, я предпочитаю print "Hello World\n"
чудовищному 700-строчному коду, в который его переводит perlcc
. Я не видел, чтобы эти программы производили что-либо, что могло бы пройти проверку кода, а также написанный элегантный код C. OTOH, если вам нужен компилятор, потому что вы не хотите распространять исходный код незапутанным способом, тогда perlcc
может творить чудеса.
RPerl может обеспечить ускорение, но очень ограничен в том, что он может переводить.
Пример тривиального «элегантного, но не правильного» транслятора см. в прототипе perl2c++.pl. Это работает путем замены (несколько) стандартных Perl-измов на C++-измы. C++ был выбран потому, что это язык высокого уровня, как и Perl, но он все еще разделяет тот же дух «голого железа», что и C.
В случае простого генератора псевдослучайных чисел LCG LCG.pl вывод perl2c++.pl
представляет собой чистый и лаконичный код C++, который работает в десятки раз быстрее, чем исходный Perl, и не зависит ни от каких библиотек Perl. Его можно расширить, чтобы найти все стандартные ответы на вопрос «Как сделать X на Perl» и заменить его на «Как сделать X на C++». Затем он может успешно перевести множество простых, но реальных сценариев Perl и помочь человеку перевести нетривиальное программное обеспечение Perl в элегантный код C++. Это было бы очень полезно, если вы пишете программы для вычислений на Perl, которые изначально должны были быть написаны на C++.
Для программного обеспечения, для которого Perl хорошо подходит, но вы просто хотите работать немного быстрее, подход JIT, используемый JavaScript (и, в конечном счете, Perl 6), более перспективен.
Преобразователь называется программатором, а процесс преобразования программированием. Серьезно, язык Perl настолько обширен и мощен, что любой, кто попытается написать конвертер, будет смотреть свысока на задачу всей своей жизни. Кроме того, эффект повышения производительности может быть не на порядок, так зачем беспокоиться?