Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的尾部递归优化与递归_Java_Recursion_Tail Call Optimization_Tail Call - Fatal编程技术网

Java中的尾部递归优化与递归

Java中的尾部递归优化与递归,java,recursion,tail-call-optimization,tail-call,Java,Recursion,Tail Call Optimization,Tail Call,我有一个关于尾部调用优化的问题,我需要知道这个java代码的行为: private void doSomething(int v) { inf f = someCalculation(v); if (f < 0) doSomething(v/2); else doSomething(v*2); } private void doSomething(int v){ inf f=某些计算(v); if(f

我有一个关于尾部调用优化的问题,我需要知道这个java代码的行为:

private void doSomething(int v) {

    inf f = someCalculation(v);

    if (f < 0) doSomething(v/2);
    else doSomething(v*2);

}
private void doSomething(int v){
inf f=某些计算(v);
if(f<0)剂量组(v/2);
其他剂量(v*2);
}
这段代码是一个毫无意义的例子,但我的问题是,在这种情况下:

  • 第一个doSomething()调用会被优化吗
  • 第二个doSomething()调用将被优化
  • if/else块以任何方式影响优化
  • 谢谢

    编辑:


    请提供一个示例,说明如果该语言不是Java,而是具有TCO的其他语言,那么您将如何执行此操作Java 8没有任何尾部调用优化。不会优化任何调用(转换为迭代/转到语句)

    关于Java总体拥有成本的讨论由来已久,Guy Steele是其最著名的支持者之一


    我建议阅读
    mlvm-dev
    邮件列表,以获得对该主题的最新评论。

    java8没有任何尾部调用优化。不会优化任何调用(转换为迭代/转到语句)

    关于Java总体拥有成本的讨论由来已久,Guy Steele是其最著名的支持者之一


    我建议您阅读
    mlvm dev
    邮件列表,以获取对该主题的最新评论。

    尝试运行以下代码:

    public static void main(String[] args) {
      for (int i = 1; i > 0; i *= 2) { doSomething(i); }
    }
    
    private static void doSomething(int start) {
      doSomething(start, start);
    }
    
    private static void doSomething(int i, int start) {
      if (i == 0) { System.out.println("done from " + start); }
      else { doSomething(i - 1, start); }
    }
    

    如果JVM可以在没有堆栈溢出的情况下运行它,那么这就意味着它可以进行尾部递归优化(或非常好的常量传播)。

    尝试运行以下代码:

    public static void main(String[] args) {
      for (int i = 1; i > 0; i *= 2) { doSomething(i); }
    }
    
    private static void doSomething(int start) {
      doSomething(start, start);
    }
    
    private static void doSomething(int i, int start) {
      if (i == 0) { System.out.println("done from " + start); }
      else { doSomething(i - 1, start); }
    }
    

    如果JVM可以在没有堆栈溢出的情况下运行它,那么它应该意味着它可以进行尾部递归优化(或者非常好的常量传播)。

    最后两行可以重写为
    doSomething((f<0)?(v/2):(v*2))…那么您的问题到底在哪里?有三个问题,试着提供一个答案。首先:优化几乎从来都不是保证。某些东西可以被优化并不意味着它会被优化,特别是在Java中,当代码被“及时”优化时。@GiulioFranco Tail call optimization是一个定义良好的概念,在支持它的语言中被确定性地(静态地)应用。事实上,它是如此普遍,以至于支持它的语言可以称为“TCO语言”。@MarkoTopolnik所有(或许多)优化都是一个定义良好的概念。通常不容易做到的是确定这个概念是否适用于我们编写的代码。如果某些语言标准化了tco适用且必须应用的条件,我不知道。最后两行可以重写为
    doSomething((f<0)?(v/2):(v*2))…那么您的问题到底在哪里?有三个问题,试着提供一个答案。首先:优化几乎从来都不是保证。某些东西可以被优化并不意味着它会被优化,特别是在Java中,当代码被“及时”优化时。@GiulioFranco Tail call optimization是一个定义良好的概念,在支持它的语言中被确定性地(静态地)应用。事实上,它是如此普遍,以至于支持它的语言可以称为“TCO语言”。@MarkoTopolnik所有(或许多)优化都是一个定义良好的概念。通常不容易做到的是确定这个概念是否适用于我们编写的代码。如果某些语言标准化了tco适用且必须适用的条件,我不知道。我读到Java 8有某种tco,但我真的无法理解,因为有人说它有,其他人说没有。。。。所以最后的答案是,根本没有TCO?HotSpot的JIT编译器中可能有一些东西(虽然个人从未听说过),但Java规范中肯定没有任何东西。所以,既然你不能保证某个习惯用法不会破坏堆栈,那就没什么用处了。java 12呢?我读到java 8有某种TCO,但我真的无法理解,因为有人说它有,其他人说没有。。。。所以最后的答案是,根本没有TCO?HotSpot的JIT编译器中可能有一些东西(虽然个人从未听说过),但Java规范中肯定没有任何东西。所以,既然你不能保证某个习惯用法不会破坏堆栈,那就没什么用处了。那么java 12呢?如果tail调用是最后一条指令,那么可以实现AIK TCO,那么如果我将“return doSomething()”之类的内容作为最后一条指令,会发生什么呢?return语句是否算作最后一条指令,因此无法执行TCO?
    return doSomething()
    是可优化尾部调用的典型示例。更重要的是,因为TCO的主要用例是递归纯函数,根据定义,这些函数永远不会
    void
    。如果尾部调用是最后一条指令,那么可以完成AFAIK TCO,那么如果我将“return doSomething()”作为最后一条指令,会发生什么呢?return语句是否算作最后一条指令,因此无法执行TCO?
    return doSomething()
    是可优化尾部调用的典型示例。更重要的是,只需
    doSomething()
    ,因为TCO的主要用例是递归纯函数,根据定义,这些函数永远不会
    void