【发布时间】:2010-11-10 00:43:52
【问题描述】:
是否有可用的工具将 Perl 中的源代码转换为 C 中的源代码?任何平台都可以。
【问题讨论】:
是否有可用的工具将 Perl 中的源代码转换为 C 中的源代码?任何平台都可以。
【问题讨论】:
对此的规范答案是MJD's "Why Not Translate Perl to C?"。
【讨论】:
perlcc 将 Perl “翻译”为 C。
它并不是真正的 Perl 到 C 编译器;它的输出只是 Perl 解释器和程序的已解析字节码的捆绑包。
【讨论】:
B::C 和B::CC 似乎都坏了。
答案几乎是“不”。 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" 而不是 perlcc 将其翻译成的 700 行长的怪物。我还没有看到这些程序产生的任何东西都可以通过代码审查以及编写优雅的 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 方法更有希望。
【讨论】:
转换器被称为programmer,转换过程programming。说真的,perl 本身的语言是如此庞大和强大,以至于任何试图编写转换器的人都会看不起这项终生的任务。此外,性能提升的效果可能不是一个数量级,那何必呢?
【讨论】: