2011-08-19 36 views
6

首先,請隨時糾正我的問題的標題,我不太熟悉函數式編程術語。Scala - 調用'頭等函數'的開銷

我的問題是,是否存在將函數當作'變量內容'的任何開銷(以及它的重要性)。例如,在下面的代碼:

class Processor { 
    val map = Map[Class[_],AnyRef => Something](...) 

    def process(c:AnyRef):Something = map(c.getClass)(c) 
    def worksFor:List[Class[_]] = map.map(_._1) 
} 

是非常好的,比起:

class Processor { 
    def worksFor = List(classOf[Bears], classOf[Beets], classOf[BattlestarGalactica]) 

    def process(c: AnyRef) = { 
    c match { 
     case c: Bears .... 
     . 
     . 
     . 
    } 
    } 
} 

但它執行任何惡化? (顯然它會佔用更多的內存,因爲地圖)

感謝您的任何回答!

回答

11

當您將函數指定爲值時,創建的對象是其中一個函數類的實例(如果它帶有單個參數,則爲Function1,如果帶有兩個參數,則爲Function2等)。實際上調用該函數只是調用FunctionN對象上的apply方法。

在這方面,除非您正在尋找一個關鍵循環,否則確實有很少的開銷。理論上,創建一個對象來表示這個函數 - 一個沒有內部狀態,一個非常小的類(包含或多或少只是實現函數的代碼)。由於這個對象的使用方式有限,我希望Hotspot能夠在這裏應用很多優化。然後,與match聲明相比,函數的apply方法將會有一個額外的方法調度。再次,這是一個固定的(和普通的)模式,我期望它可以被優化很多。


基本上,任何開銷都可以忽略不計。就所有的優化而言,以人爲簡潔/不自然的方式編寫代碼爲時尚早,直到您發現它是性能瓶頸爲止。

如果性能真的是一個關鍵問題,那麼你很有可能最終會選擇比選項更優化的選項。

與此同時,放鬆和享受一流的功能給你的「好」!

+0

感謝您的詳細解答。我很高興我可以使用第一個選項,然後:) – Arg