繁体   English   中英

Java 编译与 Perl 编译

[英]Java Compilation vs Perl Compilation

Java 和 Perl 的编译过程有何不同? 两者都产生一个字节码,但之后会发生什么? perl 中的解释和 java 中从目标代码到机器代码的转换是否完全不同? 如果是这样,那么为什么 Java 不能成为脚本语言?

这个问题没有明确的答案,但无论如何我都会尝试。

Java 可以更积极地编译代码,因为它不像 Perl 那样动态。 Java 不适合作为脚本语言的原因是

  • 你必须编写相当多的代码才能做一些简单的事情。 例如,“hello world”是 5 行。
  • 与 Perl 相比,文件和字符串操作相对复杂。
  • 很难从 Java 运行另一个程序。
  • 您可以使用 BeanShell 或 Groovy 编写 Java 脚本,但您不会,因为有一长串语言是更好的选择。 例如 bash 开始。

Java 和 Perl 本身不是编译或解释的语言,但两者都只有一个主要实现。

爪哇

Java 源代码提前编译为可移植的字节码。 在此步骤中应用了一些优化。 该字节码随后由 JVM 执行,通过解释或 JIT 编译,由 JVM 选择。 该语言中没有任何内在的东西会阻止编译 + 执行。

珀尔

在 perl 解释器中,VM 和编译器是紧密集成的。 即使在解析源代码期间,某些部分也可能已经执行。 每个可执行单元产生一个“操作码树”,它同时具有 AST 和字节码的作用。 这种增量编译意味着不可能真正将编译与执行分开,尽管有时可以缓存编译结果,或缓存到 optree 的 JIT 部分。 然后解释操作码。

比较

Perl 的编译速度比 Java 快得多,但只应用了很少的优化,例如常量折叠或删除不必要的操作码。 更复杂的优化对于脚本使用来说太昂贵了。 缺乏 JIT 支持和高级优化也意味着 Perl 通常比 Java 慢得多。

原则上,两个 VM(JVM 和 perl)也可用于其他语言。 缺乏正式规范和以 Perl 为中心的实现意味着没有其他语言将 perl 解释器用作 VM,而许多语言可以编译为 JVM 字节码(示例包括 Python、Ruby、Perl6、Clojure 等语言)。

但是,JVM 针对服务器软件或桌面应用程序等长时间运行的程序进行了优化。 这使得执行代价高昂的优化成为一种可行的权衡。 OTOH Perl 不仅用于大型程序,还用于启动成本很重要的小型工具。 因此,简单的 Perl 脚本可能只需要 2 MB 的内存,并且可以比 JVM 单独启动所需的速度更快。 虽然 JVM用于编写脚本,但启动成本和极端内存使用量通常使其缺乏吸引力。

术语说明:脚本是在不手动编译的情况下执行程序。 这与解释与编译无关。 在 Unix 中, shebang可用于指定脚本的解释器。

首先要注意的是,“编译过程”不是各自语言所固有的。 相反,它们是相应语言的特定实现的方面。 (即使是 Java 字节码、JVM 和相关的东西也是实现细节……并不是所有 Java 语言的实现都通用。)

编译为字节码后的“接下来会发生什么”是……依赖于实现。

  • 对于 Java,字节码通常会被解释一点(以收集一些统计信息),然后编译为本机代码。 但不总是; 例如查找java -int命令选项。 从技术上讲,甚至不需要在图片的任何地方都有字节码。 (虽然使用商标“Java”存在法律问题......)

  • 对于 Perl,我的理解是字节码通常只是被解释。 但其他问题是 Perl 编译器可以生成其他形式的代码,并且 Perl 可以直接解释 Perl 编译器前端生成的“内部形式”。

所以回答你的问题:

Java 和 Perl 的编译过程有何不同?

看上面。 在这两种情况下,它都比您描述的要复杂。

两者都产生一个字节码......

同样,不一定正确。

……但是在那之后会发生什么? perl 中的解释和 java 中从目标代码到机器代码的转换是否完全不同?

由于各自“虚拟机”的性质,“字节码”指令集必然会有所不同。 JVM 本质上是一种静态类型的东西,其中每个变量和表达式的形式类型都是已知的……可以是原始类型或某种对象类型。 相比之下,由于 Perl 语言的性质,Perl VM 需要(更多)动态类型化。

如果是这样,那么为什么 Java 不能成为脚本语言?

很明显,“如果是这样”部分不满足......存在显着差异。

但是(IMO)Java 不是一个好的脚本语言有更充分的理由:

  • Java相对冗长
  • Java 坚持声明类型和变量
  • Java本质上是静态类型检查的
  • Java 对函数式编程(例如一等和高阶函数)的支持传统上很差(尽管这正在改进......)
  • Java 扩展语言核心的能力有限(就像典型的脚本语言一样)
  • (典型)JVM 的启动时间比常规脚本语言要长得多。

这些因素结合在一起使 Java 成为编写脚本的糟糕选择1, 2 但另一方面,它们使 Java 成为需要更高性能和提高静态编译时类型可靠性的情况的不错选择。

(从某种意义上说,字节码的使用和编译过程的性质对于脚本与非脚本而言在很大程度上无关紧要......前提是编译不太慢......在错误的时间。)


1 - Java 9 版本引入了“jshell”命令,它允许您以交互方式运行 Java。 不幸的是,它并不真正适合脚本编写,因为“jshell”脚本无法访问命令行参数。

2 - Java 11 版本允许您使用如下命令编译和运行单个 Java 源文件: java SomeCommand.java 这仍然存在 JVM 启动缓慢的问题,以及字节码编译步骤源的额外开销。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM