Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.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
递归GO vs Scala_Scala_Go_Fibonacci - Fatal编程技术网

递归GO vs Scala

递归GO vs Scala,scala,go,fibonacci,Scala,Go,Fibonacci,以下Scala代码在1.5分钟内完成,而GO finish中的等效代码在2.5分钟内完成。 最多fib(40)都需要2秒。间隙出现在fib(50) 我得到的印象是,作为本地人,GO应该比Scala更快 斯卡拉 去 Scala优化? 戈朗极限 正如“我的另一辆车是cadr”所说的,问题是“为什么Scala在这个特殊的微基准上比GO快?” 忘记斐波那契吧,假设我有一个需要递归的函数。 Scala在递归情况下更优越吗 它可能是一个内部编译器实现,甚至是特定于Scala的优化。 如果你知道,请回答 在1

以下Scala代码在1.5分钟内完成,而GO finish中的等效代码在2.5分钟内完成。
最多fib(40)都需要2秒。间隙出现在fib(50)
我得到的印象是,作为本地人,GO应该比Scala更快

斯卡拉

Scala优化?
戈朗极限

正如“我的另一辆车是cadr”所说的,问题是“为什么Scala在这个特殊的微基准上比GO快?”

忘记斐波那契吧,假设我有一个需要递归的函数。
Scala在递归情况下更优越吗

它可能是一个内部编译器实现,甚至是特定于Scala的优化。
如果你知道,请回答

在12秒内循环运行1500000000次


Scala解决方案将使用堆栈,因为它不是尾部递归的(添加发生在递归调用之后),但它不应该创建任何垃圾

对于这种代码模式,您正在使用的热点编译器(可能是服务器)很可能是比Go编译器更好的编译器


如果你真的很好奇,你可以。

对于Go,使用迭代而不是递归。递归可以用显式堆栈的迭代来代替。它避免了函数调用和调用堆栈管理的开销。例如,使用迭代并将
n
从50增加到1000几乎不需要时间:

package main

import "fmt"

func fib(n int) (f int64) {
    if n < 0 {
        n = 0
    }
    a, b := int64(0), int64(1)
    for i := 0; i < n; i++ {
        f = a
        a, b = b, a+b
    }
    return
}

func main() {
    n := 1000
    fmt.Println(n, fib(n))
}
使用适当的算法。避免指数时间复杂性。当性能很重要时,不要对斐波那契数使用递归

参考:

我们观察到分支递归算法的计算效率低下 几乎所有的教科书都没有适当地涵盖函数 计算机科学课程在课程的前三年。 斐波那契数和二项式系数常用作 分支递归函数的示例。然而,他们的收入呈指数增长 时间复杂性很少有人提出,也从未在实践中得到完全证明 教科书。很少使用替代线性时间迭代解 提到。我们给出了这些递归函数的简单证明 具有指数时间复杂度

递归是定义和算法的有效技术 只进行一次递归调用,但如果 它进行两个或更多递归调用。因此,递归方法是可行的 通常作为概念性工具而不是工具更有用 高效的计算工具。本文给出的证明是正确的 成功地(在五年期间)向一年级学生授课 在渥太华大学。有人建议将递归作为 第二部分将介绍问题解决和定义工具 第一门计算机科学课程。然而,递归编程应该 推迟到课程结束时(或者最好在 第二门计算机科学课程的开始),迭代之后 程序被很好地掌握,堆栈操作也被很好地理解


我看不到任何优化,它是指数的,递归斐波那契的同一个例子被用来说明如何不编写递归函数。看起来,这种效果是因为一些实现的细微差别,可能是垃圾收集,可能是进程可用的内存(比如,出于某种原因,在scala中,对于任务和go-not来说,它已经足够了)。我会在峰值检查内存消耗。因为Scala是JIT编译的,所以它可以在几个递归调用之后执行一些特别的内存化。我已经让JVM在循环展开方面做了一些非常好的优化。虽然go代码被编译成机器代码,但运行时仍然进行所有内存和堆栈管理,所以JVM基本上是一样的。我并不惊讶JVM比go优化得更好。问题不是“我如何才能更快地计算斐波那契”。问题是“为什么Scala在这个特殊的微基准中比GO快”。@Myothercarisacadr:仔细阅读这个问题。这个问题问的是从fib(40)到fib(50)的时间跳跃,从2秒到1.5到2.5分钟。这个答案为围棋解决了这个问题。对于Scala来说,这可能是一个类似的答案。如果可以的话,你应该始终使用迭代——递归是懒惰的程序员工具。我不完全同意。您可以通过递归获得相同的复杂性,因为您可以。
func fib(n int) (ret int) {
    if n > 1 {
        return fib(n-1) + fib(n-2)
    }
    return n
}
func fib(n int) (two int) {
    one := 0
    two = 1
    for i := 1; i != n; i++ {
        one, two = two, (one + two)
    }
    return
}
package main

import "fmt"

func fib(n int) (f int64) {
    if n < 0 {
        n = 0
    }
    a, b := int64(0), int64(1)
    for i := 0; i < n; i++ {
        f = a
        a, b = b, a+b
    }
    return
}

func main() {
    n := 1000
    fmt.Println(n, fib(n))
}
$ time .fib
1000 8261794739546030242
real    0m0.001s
user    0m0.000s
sys 0m0.000s