2012-02-25 41 views
5

在很多使用Scala的情況下,比如簡單的局部範圍的函數調用,可以想象它通常會在理論上可能完全擺脫函數對象。但是AFAIK,JVM不知道如何做到這一點,而且我也不認爲Scala會這樣做。正確?Scala(或JVM)是​​否曾經優化(函數)對象?

匿名函數對象是否總是密封的?如果沒有,那麼可以完成多少內聯有一個相當嚴格的限制。正確?

有沒有人知道有可能解決這些優化問題的計劃工作?

另見相關的純Java的問題:Does a modern JVM optimize simple inline anonymous class allocation?

(吟唱的「不優化太早」,「沒關係」,等是非常冗餘在這一點上,而不是有用)。

+1

你是什麼意思擺脫功能對象?你的意思是他們的代碼是內聯的嗎?或者在代碼被內聯後,持有該函數的對象被垃圾收集? – Bill 2012-02-25 04:23:11

+0

@Bill,對不起,不清楚。我的意思是從來沒有創造的對象。在許多情況下,特別是對於匿名局部函數,它實際上是無狀態的,並且應用方法有效地是靜態的。 – 2012-02-25 16:05:49

回答

5

內聯加逃逸分析可以做到這一點。你可以證明這一點給自己,如果你使用JVM 7編制報告,或基準的代碼下面的兩個片段:

def rfor(i0: Int, i1: Int)(f: Int => Unit) { 
    var i = i0 
    while (i <= i1) { 
    f(i) 
    i += 1 
    } 
} 

def whiley = { 
    var s = 0 
    var n = 1 
    while (n <= 500000000) { 
    val k = n >> 2 
    var i = 1 
    while (i <= 2) { 
     s += i*k 
     i += 1 
    } 
    n += 1 
    } 
    s 
} 

def rfory = { 
    var s = 0 
    var n = 0 
    while (n <= 500000000) { 
    val k = n >> 2 
    rfor(1, 2){ s += k * _ } 
    n += 1 
    } 
    s 
} 

在我的機器,第二個是至少以最快的速度第一個(有時更快),儘管第二個似乎需要每隔一次迭代創建函數。