JVM原生不支持尾递归优化,但是Scala编译器支持

The JVM doesn’t support TCO natively, so tail recursive methods will need to rely on the Scala compiler performing the optimization.----------"Scala in Depth" 3.5.2

Jvm本身是不支持尾递归优化得,需要编译器支持,而Java编译器不支持,但是Scala支持。写一个简单的计算1到n的和的递归算法验证一下。

public class TestTailRecursion {

    private static long sum(long n, long total) {
        if (n <= 0) {
            return total;
        }
        return sum(n - 1, total + n);
    }

    public static void main(String[] args) {
        long sum = sum(100000, 0);
        System.out.println(sum);
    }
}

10w(可能每个机器不一样)的时候栈溢出。

object TestTailRecursion {

  def sum(n: Long, total: Long): Long = {
    if (n <= 0) total
    else sum(n - 1, total + n)
  }

  def main(args: Array[String]) {
    val total = sum(10000000, 0)
    println(total)
  }
}

Scala表示毫无压力。

可以讲Scala编译得到的bytecode用JavaDecompiler反编译,看到如下:

import scala.Predef.;
import scala.runtime.BoxesRunTime;

public final class TestTailRecursion$
{
  public static final  MODULE$;

  private TestTailRecursion$()
  {
    MODULE$ = this;
  }

  public long sum(long n, long total)
  {
    for (;;)
    {
      if (n <= 0L) {
        return
          total;
      }
      total += n;n -= 1L;
    }
  }

  public void main(String[] args)
  {
    long total = sum(10000000L, 0L);
    Predef..MODULE$.println(BoxesRunTime.boxToLong(total));
  }

  static
  {
    new ();
  }
}
时间: 2024-08-07 02:58:50

JVM原生不支持尾递归优化,但是Scala编译器支持的相关文章

【Scala】尾递归优化

以递归方式思考 递归通过灵巧的函数定义,告诉计算机做什么.在函数式编程中,随处可见递归思想的运用.下面给出几个递归函数的例子: object RecursiveExample extends App{ // 数列求和例子 def sum(xs: List[Int]): Int = if (xs.isEmpty) 1 else xs.head + sum(xs.tail) // 求最大值例子 def max(xs: List[Int]): Int = if (xs.isEmpty) throw n

对SNL语言的解释器实现尾递归优化

对于SNL语言解释器的内容可以参考我的前一篇文章<使用antlr4及java实现snl语言的解释器>.此文只讲一下"尾递归优化"是如何实现的--"尾递归优化"并不是一个语言实现必须要做的,但这是一个比较有趣的东西,所以我还是想拿来讲一讲. 在前一篇文章中有一个例子: program recursion    procedure f(integer d);    begin        write(d);        f(d + 1)    endbe

Python开启尾递归优化!

本文和大家分享的主要是python中尾递归相关使用方法,希望通过本文的分享能帮助大家更好的学习python语言,一起来看看吧. 一般递归与尾递归 一般递归 def normal_recursion(n): if n == 1: return 1 else: return n + normal_recursion(n-1) 执行: normal_recursion(5)5 + normal_recursion(4)5 + 4 + normal_recursion(3)5 + 4 + 3 + nor

Lua function函数,可变参数, 局部函数,尾递归优化

在Lua中,函数是作为"第一类值"(First-Class Value),这表示函数可以存储在变量中,可以通过参数传递给其他函数,或者作为函数的返回值(类比C/C++中的函数指针),这种特性使Lua具有极大的灵活性. Lua对函数式编程提供了良好的支持,可以支持嵌套函数. 另外,Lua既可以调用Lua编写的函数,还可以调用C语言编写的函数(Lua所有的标准库都是C语言写的). 定义一个函数 function hello() print('hello') end hello函数不接收参数

深入JVM内核---原理,诊断与优化

JVM的概念 JAM是Java Virtual Machine的简称.意为Java虚拟机 虚拟机 指通过软件模拟的具有完整硬件系统功能的,运行在一种完整隔离环境中的完整计算机系统 有哪些虚拟机 - VMWare -Visual Box -JVM VMWare或者Visual Box都是使用软件模拟物理CPU的指令集 JVM使用软件模拟Java字节码的指令集 JVM发展史 初始JVM-Java和JVM的历史 1996年SUN JDK1.0Classic VM -纯解释运行,使用外挂进行JIT 19

Gcc 优化选项 与尾递归优化

今天做高性能计算机系统的作业的时候,发现gcc中的优化选项有很多应用 . 例如对于C源码: #include <stdio.h> #include <stdlib.h> int main() { int x[101],y[101]; int a,i; a = 5; for(i=0;i<=100;i++) { x[i] = i+1; y[i] = i; } for(i=100; i>=0; i--) y[i] += a*x[i]; return 0; } 1.直接用gcc

.NET 4.6的RyuJIT尾递归优化的Bug

今天看到园子里有一篇新闻稿.NET 4.6的RyuJIT编译器中发现严重的Bug提到,在.Net 4.6的x64程序中默认启用新的JIT程序RyuJIT在处理尾递归指令的时候有一个Bug,导致无法得到正确的结果. 微软在其官方BlogRyuJIT Bug Advisory in the .NET Framework 4.6更是较为详细的介绍了这一bug.虽然尾递归使用得并不多(貌似在F#中有很多应用),但这个bug算是比较严重的了: 这个问题只有在应用了代码优化之后才会出现,由于多数开发者与项目

一个很Cool的Idear-&gt;Python的尾递归优化

偶然在国外一个网站瞅到的,非常的酷,发出来共享一下.一般来说,Python和Java,C#一样是没有尾递归自动优化的能力的,递归调用受到调用栈长度的限制被广泛的诟病,但是这个狂人用一个匪夷所思的方法解决了这个问题并在Python上实现了,从此Python的递归调用再也不用受到调用栈长度的制约,太酷了. 首先我们还是从递归说起,之前我发过一篇 <浅谈递归过程以及递归的优化>其中用到了斐波那契数来作为例子.线性递归的算法由于太过一低效就被我们Pass掉了,我们先来看尾递过方式的调用: 1 def 

尾递归优化

来自廖雪峰的官方网站 fact(n)可以表示为n x fact(n-1),只有n=1时需要特殊处理. 于是,fact(n)用递归的方式写出来就是: def fact(n): if n==1: return 1 return n * fact(n - 1) 上面就是一个递归函数.可以试试: >>> fact(1) 1 >>> fact(5) 120 >>> fact(100) 933262154439441526816992388562667004907