以下 Scala 代码在 1.5 分钟内完成,而 GO 中的等效代码在 2.5 分钟内完成。
直到 fib(40) 都需要 2 秒。 fib(50) 出现缺口
我的印象是 GO 是原生的,应该比 Scala 更快。
斯卡拉
def fib(n:Int):Long = {
n match {
case 0 => 0
case 1 => 1
case _ => fib(n-1) + fib(n-2)
}
}
开始
func fib(n int) (ret int) {
if n > 1 {
return fib(n-1) + fib(n-2)
}
return n
}
Scala 优化?
Golang 限制?
正如“My other car is a cadr”所说的那样,问题是“为什么 Scala 在这个特定的微基准测试中比 GO 快?”
忘记斐波那契吧,假设我确实有一个需要递归的函数。
Scala 在递归情况下是否更优越?
它可能是一个内部编译器实现,甚至是 Scala 特定的优化。
知道的请回答。
在 12 秒内循环运行 15000000000
func fib(n int) (two int) {
one := 0
two = 1
for i := 1; i != n; i++ {
one, two = two, (one + two)
}
return
}
最佳答案
对于 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))
}
输出:
$ time .fib
1000 8261794739546030242
real 0m0.001s
user 0m0.000s
sys 0m0.000s
使用适当的算法。避免指数时间复杂度。当性能很重要时,不要对斐波那契数使用递归。
引用:
Recursive Algorithms in Computer Science Courses: Fibonacci Numbers and Binomial Coefficients
We observe that the computational inefficiency of branched recursive functions was not appropriately covered in almost all textbooks for computer science courses in the first three years of the curriculum. Fibonacci numbers and binomial coefficients were frequently used as examples of branched recursive functions. However, their exponential time complexity was rarely claimed and never completely proved in the textbooks. Alternative linear time iterative solutions were rarely mentioned. We give very simple proofs that these recursive functions have exponential time complexity.
Recursion is an efficient technique for definitions and algorithms that make only one recursive call, but can be extremely inefficient if it makes two or more recursive calls. Thus the recursive approach is frequently more useful as a conceptual tool rather than as an efficient computational tool. The proofs presented in this paper were successfully taught (over a five-year period) to first year students at the University of Ottawa. It is suggested that recursion as a problem solving and defining tool be covered in the second part of the first computer science course. However, recursive programming should be postponed for the end of the course (or perhaps better at the beginning of the second computer science course), after iterative programs are well mastered and stack operation well understood.
关于scala - 递归 GO 与 Scala,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24795294/
我有一个涉及多台机器、消息队列和事务的问题。因此,例如用户点击网页,点击将消息发送到另一台机器,该机器将付款添加到用户的帐户。每秒可能有数千次点击。事务的所有方面都应该是容错的。我以前从未遇到过这样的事情,但一些阅读表明这是一个众所周知的问题。所以我的问题。我假设安全的方法是使用两阶段提交,但协议(protocol)是阻塞的,所以我不会获得所需的性能,我是否正确?我通常写Ruby,但似乎Redis之类的数据库和Rescue、RabbitMQ等消息队列系统对我的帮助不大——即使我实现某种两阶段提交,如果Redis崩溃,数据也会丢失,因为它本质上只是内存。所有这些让我开始关注erlang和
我有一个随机大小的散列,它可能有类似"100"的值,我想将其转换为整数。我知道我可以使用value.to_iifvalue.to_i.to_s==value来做到这一点,但我不确定我将如何在我的散列中递归地做到这一点,考虑到一个值可以是一个字符串,或一个数组(哈希或字符串),或另一个哈希。 最佳答案 这是一个非常简单的递归实现(尽管必须同时处理数组和散列会增加一些技巧)。deffixnumifyobjifobj.respond_to?:to_i#IfwecancastittoaFixnum,doit.obj.to_ielsifobj
我经常迷上ruby的一件事是递归模式。例如,假设我有一个数组,它可能包含无限深度的数组作为元素。所以,例如:my_array=[1,[2,3,[4,5,[6,7]]]]我想创建一个方法,可以将数组展平为[1,2,3,4,5,6,7]。我知道.flatten可以完成这项工作,但这个问题是作为我经常遇到的递归问题的一个例子-因此我试图找到一个更可重用的解决方案。简而言之-我猜这种事情有一个标准模式,但我想不出任何特别优雅的东西。任何想法表示赞赏 最佳答案 递归是一种方法,它不依赖于语言。您在编写算法时要考虑两种情况:再次调用函数的情
我有这个ruby代码:defget_sumnreturn0ifn似乎正在为999之前的值工作。当我尝试9999时,它给了我这个:stackleveltoodeep(SystemStackError)所以,我添加了这个:RubyVM::InstructionSequence.compile_option={:tailcall_optimization=>true,:trace_instruction=>false}但什么也没发生。我的ruby版本是:ruby1.9.3p392(2013-02-22revision39386)[x86_64-darwin12.2.1]我还增加了机器的堆栈大
构建一个深度优先的网络蜘蛛,这意味着它将访问第一页上的所有链接,然后转到每个链接,并访问所有第二页上的链接...你应该使用递归吗?我发现这是CPU密集型的。defrecursion()linkz_on_first_page.eachdo|link|recursion(link)endendrecursion(firstpage) 最佳答案 绝对不是,由于万维网的实际性质,您很快就会遇到问题。当您访问带有主导航部分的网站时,每个页面都链接到其他页面,您就进入了一个无限循环。您可以跟踪您处理了哪些链接,但即便如此,递归循环并不真正适合万
例如,如果我有YAML文件en:questions:new:'NewQuestion'other:recent:'Recent'old:'Old'这最终会变成一个json对象,例如{'questions.new':'NewQuestion','questions.other.recent':'Recent','questions.other.old':'Old'} 最佳答案 由于问题是关于在Rails应用程序上使用YAML文件进行i18n,因此值得注意i18ngem提供了一个辅助模块I18n::Backend::Flatten完全像
在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol
我有这两个gcd函数的实现:defgcd1(a,b)ifa==baelsifa>bif(a%b)==0belsegcd1(a%b,b)endelseif(b%a)==0aelsegcd1(a,b%a)endendenddefgcd2(a,b)if(a==b)returnaelsifb>amin,max=a,belsemin,max=b,aendwhile(max%min)!=0min,max=max%min,minendminend函数gcd1是尾递归的,而gcd2使用while循环。我已经验证rubinius通过对阶乘函数进行基准测试来执行TCO,只有阶乘函数基准测试显示递归版本和迭
我想显示一个由gem祖先管理的类别树。我想使用一个助手,它会递归地遍历树并一个一个地返回类别,暂时没有html标签或内容。moduleCategoriesHelperdefdisplay_tree(category)ifcategory.has_children?category.children.eachdo|sub_category|display_tree(sub_category)puts(sub_category.name)#tocheckifitgoeshereendendcategory.nameendendcategory参数是根类别之一。它应该返回什么?在网页中:它仅
我有一个grammarfile对于我正在尝试构建的一种新的通用编程语言。我正在努力使该语言健壮且易于使用(它深受Ruby等启发),为此我引入了一些左递归规则。我看到一些例子似乎表明了以下左递归规则:rulel_recursel_recurse/'somethingelse'end可以通过将其更改为非左递归:ruler_recurse'somethingelse'/r_recurseend对我来说,这看起来会有不同的问题并且仍然会失败。我是对的,还是这会“奏效”?我试图(查找和)消除的特定左递归可以在这个grammarfile中找到.我不确定哪些规则受到影响,但至少somewerepoi