【问题标题】:Tail Call Optimisation in JavaJava 中的尾调用优化
【发布时间】:2019-04-20 15:33:08
【问题描述】:

从 Java 8 开始,Java 不提供尾调用优化 (TCO)。 在研究它时,我知道reason是:

在 JDK 类中 [...] 有许多安全敏感方法,它们依赖于 JDK 库代码和调用代码之间的堆栈帧计数来确定谁在调用它们。

然而,基于 JVM 的 Scala 支持尾调用优化。 Scala 在编译时进行尾递归优化。为什么 Java 不能使用相同的方法?

PS:不确定 Java 的最新版本(截至目前为 Java 11)现在是否具有 TCO。如果知道的人也可以分享一下就好了。

注意事项:

  1. 我知道 TCO 处于积压状态并且优先级较低,但我想知道为什么 Java 不能像 Scala 那样在编译时进行更改。

  2. Java 没有尾调用优化,原因与大多数命令式语言没有它的原因相同。命令式循环是该语言的首选风格,程序员可以用命令式循环代替尾递归。 (Source)

【问题讨论】:

  • 从视频中,我了解到 TCO 可以在运行时完成,但为此,需要在 JVM 级别进行更改。 Java 不使用类似方法并在 javac 中进行更改的任何具体原因
  • Java 没有尾调用优化,原因与大多数命令式语言没有它的原因相同。命令式循环是该语言的首选风格,程序员可以用命令式循环代替尾递归。
  • 是的。想在这里分享信息。这不是正确的方法吗?
  • 是的。好多了。
  • Java 编译器 几乎没有任何优化。各种 JVM。特别是HotSpot,做了各种优化,但显然不是这个。请注意,Scala 不用于编译底层 JDK,这可能可以解释它。

标签: java recursion compilation jvm tail-recursion


【解决方案1】:

为什么 Java 不能使用相同的方法?

我不能说会使用哪种方法,但在Project Loom's proposal中有更好的解释:

由于毫无疑问需要向 JVM 添加操作调用堆栈的能力,因此该项目的目标也是添加一个更轻量级的结构,允许将堆栈展开到某个点,然后调用一个方法给定参数(基本上是有效尾调用的概括)。我们将该功能称为展开和调用,或 UAI。向 JVM 添加自动尾调用优化不是本项目的目标。

据我所知,尾调用的工作尚未开始,因为纤维和延续目前似乎是更高的优先级。

【讨论】:

  • 有什么更新吗? JVM 中的 TCO 期待已久。
【解决方案2】:

我在这里阅读了一篇关于如何在 Java 中实现尾递归的非常好的博文: Knoldus blog post on Java tail recursion

但是,他们博客上的代码无法编译,所以我用他们的代码创建了一个小型 repo,但修复了语法以便编译。 Github repo with working code

希望这对某人有用,我发现 Knoldus 博客文章中提出的想法非常有趣。

编辑:实际上我后来发现博客文章中提出的想法最初是 Venkat Subramaniam 的。他在here 的演讲中讨论了这些主题。

【讨论】:

    猜你喜欢
    • 2014-05-16
    • 2012-08-19
    • 2011-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 2014-04-06
    • 1970-01-01
    相关资源
    最近更新 更多