是否有可用的工具将 Perl 中的源代码转换为 C 中的源代码?任何平台都可以。
6 回答
对此的典型答案是MJD 的“为什么不将 Perl 翻译成 C?” .
有perlcc将 Perl“翻译”成 C。
它不是真正的 Perl 到 C 编译器;它的输出只是 Perl 解释器和程序的已解析字节码的捆绑包。
答案几乎是“不”。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。如果要打印大量数据,那么该程序消耗几个 100MBytes 的内存并不少见。
所以,我仍然有充分的理由将计算布局的部分移到 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"
700 行长的怪物。perlcc
我还没有看到这些程序产生的任何东西都可以通过代码审查以及编写优雅的 C 代码。OTOH,如果您想要一个编译器,因为您不想以非混淆方式分发您的源代码,那么perlcc
可以创造奇迹。
RPerl可以实现加速,但它可以翻译的内容非常有限。
有关简单的“优雅但不正确”的翻译器的示例,请参阅原型perl2c++.pl。这通过用 C++-isms 替换(一些)标准 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 本身的语言是如此庞大和强大,以至于任何试图编写转换器的人都会看不起这项终生的任务。此外,性能改进的效果可能不是一个数量级,那何必呢?