如何将Perl转换为C?

是否有可用的工具将Perl中的源代码转换为C中的源代码? 任何平台都没问题。

perlcc将Perl“翻译”为C.

它不是真正的Perl to C编译器; 它的输出只是Perl解释器的一个包和程序的解析字节码。

对此的规范回答是MJD的“为什么不将Perl转换成C?” 。

答案是非常“不”。 Perl是一种非常动态的语言。 C是静态大小数据类型的语言。 任何Perl到C的转换都可能是“执行这个子程序调用来重复模拟Perl所做的”。 构建这样的翻译器没什么意义,因为它不太可能比Perl更快地执行Perl。

我在Perl中编写了一个非常大的程序,它基于HTML和数据库查询创建PDF,实际上就像浏览器一样。 源代码总量超过1MB。 程序评估HTML,创建SQL查询和检索数据,在磁盘上搜索图像或从HTTP服务器下载图像,构建文档结构,完成所有布局计算,最后生成PDF。

我必须找到如何以多种方式加快操作。 基于此,我说Perl非常快,并且在Perl中很快完成并且成功完成了很多任务需要很长时间在C中,甚至是C ++。

有两种方法可以使Perl变慢或消耗内存:大量复杂的数据结构 – 它们需要大量内存 – 以及大量的计算。 是的,Perl的计算确实很慢。 一个简单的术语就像

 $a = $b * $c 

在Perl中非常耗时,但在任何编译语言中都非常快。 这里的操作数甚至可能是整数,而不是浮点变量 – 它很慢。 我想这就是Perl在语言枪战比赛中得分非常糟糕的原因[http://shootout.alioth.debian.org/](计算机语言基准游戏)。

我发现我的相当大的程序 – 它使用了许多Perl核心和其他CPAN模块 – 尽管被解释了,但是可以快速启动。

它表现得非常好……直到计算文本大小和布局坐标。 这非常耗时。 在说明这一点后,我写了一些小的Perl测试程序,只做了数百万次算术计算,发现它们非常慢。

此外,我使用和面向对象的方法来模拟每个布局元素。 每个对象由一个哈希表示 – 每个对象至少约10kBytes。 如果要打印大量数据,则该程序的内存消耗为几百MB。

因此,我仍然有充分的理由将计算布局的部分移动到C,使用结构我现在有固定键的哈希并且有C整数运算,现在Perl做的很慢。

但其他一切都已经完成并迅速测试并且运行得如此之快以至于我没有看到任何改变的理由。 我还发现Perl代码比C代码编写和测试更方便。 许多CPAN模块提供了您不必自己解决的解决方案。 其中许多都经过了充分的测试和记录。

在完成这个非常长篇大论之后,我得出结论:如果要成为服务器或命令行程序,请考虑Perl。 但是,如果这个程序必须建立庞大的数据结构或许多算术,那么考虑更快的事情。 有时,它可能是一个带有用C语言编写的模块的Perl程序。

有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"perlcc将其转换为700行长的怪物。 我没有看到这些程序产生任何会通过代码审查和编写优雅的C代码。 OTOH,如果你想要一个编译器,因为你不想以非混淆的方式分发你的源代码,那么perlcc可以创造奇迹。

RPerl可以实现加速,但它可以翻译的内容非常有限。

有关一个简单的“优雅但不正确”的翻译器的例子,请参阅原型perl2c ++。pl 。 这通过用C ++替换(一些)标准Perl-isms来实现。 之所以选择C ++是因为它是像Perl这样的高级语言,但仍然拥有与C相同的裸机语言。

在简单的LCG伪随机数生成器LCG.pl的情况下, perl2c++.pl的输出是干净简洁的C ++代码,其运行速度比原始Perl快几十倍,并且不依赖于任何Perl库。 它可以扩展为查找“如何在Perl上执行X”的所有标准答案,并将其替换为“如何在C ++中执行X”。 然后它可能会成功翻译许多简单但真实的Perl脚本,并帮助人类将非平凡的Perl软件翻译成优雅的C ++代码。 如果您发现自己在Perl中编写数字软件本​​来应该用C ++编写,这将是最有用的。

对于Perl非常适合的软件,但你只想更快一点,JavaScript(最终是Perl 6)使用的JIT方法更有前途。

转换器称为编程器 ,转换过程编程 。 说真的,perl的语言是如此庞大和强大,任何试图编写转换器的人都会看不起终身任务。 此外,性能改善的效果可能不是一个数量级,为什么还要费心呢?