为什么Scala中的函数调用没有优化?
我使用Scala 2.10.3运行此程序:为什么Scala中的函数调用没有优化?,scala,optimization,benchmarking,Scala,Optimization,Benchmarking,我使用Scala 2.10.3运行此程序: object Test { def main(args: Array[String]) { def factorial(x: BigInt): BigInt = if (x == 0) 1 else x * factorial(x - 1) val N = 1000 val t = new Array[Long](N) var r: BigInt = 0 for (i <- 0 un
object Test {
def main(args: Array[String]) {
def factorial(x: BigInt): BigInt =
if (x == 0) 1 else x * factorial(x - 1)
val N = 1000
val t = new Array[Long](N)
var r: BigInt = 0
for (i <- 0 until N) {
val t0 = System.nanoTime()
r = r + factorial(300)
t(i) = System.nanoTime()-t0
}
val ts = t.sortWith((x, y) => x < y)
for (i <- 0 to 10)
print(ts(i) + " ")
println("*** " + ts(N/2) + "\n" + r)
}
}
对象测试{
def main(args:Array[String]){
def阶乘(x:BigInt):BigInt=
如果(x==0)1,则x*阶乘(x-1)
val N=1000
val t=新数组[Long](N)
变量r:BigInt=0
对于(i x 例如(iScala不是一种纯粹的函数式语言,因此如果没有一个有效的系统,它就不能知道factorial
是纯粹的(例如,它对大整数的乘法一无所知)
你需要在这里添加你自己的记忆方法。最简单的方法是在你的循环之外添加一个valf300=factorial(300)
有没有办法让Scala编译器知道,factorial
是纯的(或足够纯的)@ PululcZAK没有简单的方法,除非你自己做所有的工作或者插入一些编译器插件。这里还有另外一个原因——不像编译语言,如C++或C,Scala和java编译器在编译过程中不执行积极的优化——他们推迟了大多数复杂的优化,希望JIT会做到。s代表Scala,但虽然“类型检查”效果是否正确组合,但它不会尝试处理诸如记忆函数值之类的优化。可能您可以在函数中添加一个@memoize
宏,并要求它们也是@pure
,如果记忆应该是一种语言功能或不是。Eugene Burmako实际上建议使用一个@memo
宏……在这种情况下,我不希望使用memo,因为它会击败这个微观基准。不过,我很惊讶,优化器不够聪明。例如,LLVM可以轻松地处理这种情况。编译器如何知道它是一个纯函数?如果*
在BigInt
纯粹的,然后是<代码>阶乘< /C>是纯的。我在Scala中只花了一天时间阅读编程,所以我的知识在Scala编译器的主题上太细了。我的主要观点是,在LVVM编译的C++或D中的类似代码将重复调用一个常数参数优化的函数。@ PaulJurczak,顺便说一下,你能提供S上的链接吗?在LLVM中,关于优化的一些文章、论文或一些东西?我是说,在LLVM编译的C++或D中的类似代码将对具有常数参数的函数重复调用。away@om-nom nom这里是我在D lang论坛上发布的关于此优化的帖子的链接:它不是相同的代码,而是非常相似的情况使用Scala和常量调用的de>函数未优化。