【问题标题】:How can I convert Perl to C?如何将 Perl 转换为 C?
【发布时间】:2010-11-10 00:43:52
【问题描述】:

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

【问题讨论】:

    标签: c perl converter


    【解决方案1】:

    对此的规范答案是MJD's "Why Not Translate Perl to C?"

    【讨论】:

    • -1,MJD 的旧博文来自 2001 年,并且早已过时。您不会在拆分和其他字符串处理函数中获得差异,但您将获得大量内存节省、启动时间、销毁时间以及 int、float 和 esp 的运行时间。数组处理,正如 MJD 在他的帖子末尾指出的那样。参见例如blogs.perl.org/users/rurban/2012/10/… 使用 B::CC 编译的 perl 进行 6 倍的基准测试。
    • 老实说,我很高兴看到评论中陈述了以下内容,因为我知道这很难下咽。残酷的事实.... Perl 慢得要命,但公平地说,大多数解释器也是如此,除了 lua。那篇文章具有误导性,并且非常狭隘地回答了这个问题。如果你做了 Perl 当前所做的所有低效的事情,它的编译速度仍然会非常慢。现在,如果您以某种方式手动重写您的 Perl 代码完成的含义,在 C/C++/OCAML/GO 中......我们都知道它的执行速度呈指数级增长
    • 这两篇文章都不错。我不会说 Perl 慢得要命,因为它的作用我会说它快得要命,而且看起来如果您所做的只是字符串操作和使用基本函数,那么 C 不会给您带来太多好处;数组的一个警告。如果我正确理解了 Urban 先生 2012 年的帖子,Perl 似乎有很多伴随的灵活性正在减慢速度,如果可以选择关闭其中的一些,它仍然不会比原生 C 快,但不会落后太多。程序员需要知道何时应该优化。
    • 添加我的 2 x 0.01€,使用几个字符串库,然后手动将 Perl 转换为 C,当出现正则表达式时使用该库 (...),然后,很多事情都会变得很顺利更快:当您知道类型不会改变时,避免许多 str/int 转换,在不需要正则表达式时应用常规搜索替换,subs 开销,......可能是第一次转换的一些工作,但应该更容易为下一个。实际上,我会在接下来的几周内做那种工作,我会告诉你的;)
    【解决方案2】:

    perlcc 将 Perl “翻译”为 C。

    它并不是真正的 Perl 到 C 编译器;它的输出只是 Perl 解释器和程序的已解析字节码的捆绑包。

    【讨论】:

    • perlcc 和相应的 B:: 模块由 Reini Urban 在 CPAN 上单独维护。
    • 此时B::CB::CC 似乎都坏了。
    • 这令人失望。 Cython(来自 python 的 C)运行良好,不幸的是 perl 没有可行的解决方案。
    【解决方案3】:

    答案几乎是“不”。 Perl 是一种极其动态的语言。 C 是一种用于静态大小数据类型的语言。 Perl 到 C 的任何翻译都可能是重复“执行此子例程调用以模拟 Perl 所做的事情”。而且构建这样的翻译器没有什么意义,因为它执行 Perl 的速度不可能比 Perl 快得多。

    【讨论】:

    • 好吧,Perl 有固定的数据类型,只是没有那么多。问题是 Perl 是动态的。它可能会根据多种因素进行不同的编译,这可能会改变编译器对即将到来的源代码的行为。
    【解决方案4】:

    我用 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 甚至 C++ 中都需要很长时间。" 你确定吗?请记住,Perl 是用 C 编写的,所以 Perl 所做的任何事情都已经在 C 中完成了 :-)
    【解决方案5】:

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

    对于 Perl 非常适合的软件,但您只想快一点,JavaScript(以及最终 Perl 6)使用的 JIT 方法更有希望。

    【讨论】:

      【解决方案6】:

      转换器被称为programmer,转换过程programming。说真的,perl 本身的语言是如此庞大和强大,以至于任何试图编写转换器的人都会看不起这项终生的任务。此外,性能提升的效果可能不是一个数量级,那何必呢?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-24
        • 2010-11-10
        相关资源
        最近更新 更多