最近,我开始在Scala编写很多编程竞赛代码。 (您可以在这里查看平台 - http://codeforces.com/)
关于问题的本质,我经常需要迭代数组或输入数据。例如。有一个问题陈述,说,在第一个输入行我会得到数字M,然后我需要读取M行,或整数或其他什么。我尝试使用不同的方法:
for (i <- 0 until M)
----
(0 until M).foreach
----
var i = 0
while (i < M)
---
甚至尾递归
@tailrec
def recursion(i: Int): Unit = {
if (i < M) {
doSomething()
recursion(i + 1)
}
}
所以,我的问题是哪种结构更适合Scala风格,以及更好的性能? (我正在解决的问题通常需要快速执行,否则它们不会被传递)
P.S。 我为此写了一个小测试,看起来虽然和tailrec是最好的表演者,但不是一件大事。你可以在这里看一下 - https://gist.github.com/MysterionRise/5daa63fdbd5d058528fe
答案 0 :(得分:3)
我会按照以下顺序为它们评价样式:
关于性能尾部递归和命令式将使你像循环一样快(tailrec在实践中变得非常接近while循环),并且比for / foreach更快。
附注:如果您要使用ideomatic Scala,您可能希望尝试避免副作用,而是使用.map
或使尾部递归函数返回某些内容而不是改变某些内容。
答案 1 :(得分:3)
关于效果:
请注意,如果要在JVM上编写适当的微基准,则必须考虑many effects - 例如,当JVM开始使用JIT时,同一段代码的性能会有所不同编译,然后尝试不同的优化。要在Scala中编写适当的基准,您可以查看像ScalaMeter或caliper这样的库。顺便说一句,第二个链接比较了Scala循环的不同方式,因此应该很容易适应您的用例。
但是,一般来说:
关于风格:
我完全同意约翰丹德的回答。