2014-03-28 61 views
1

在我的Groovy應用程序中,我有一個函數每秒被調用幾次,所以我想盡可能快地調用它。這個函數接收一個對象列表,然後做一些魔術,並返回另一個列表。返回列表的內容取決於傳遞給函數的列表內容。如何在Groovy中使用對象列表作爲映射關鍵字

爲了使速度更快,我想緩存返回的列表,因爲函數中的魔法不會經常更改。所以在大約99%的調用中,這個函數爲相同的參數返回相同的列表。

對於執行這樣的緩存我想使用一個地圖。此映射的關鍵應該是函數輸入參數中的列表,並且映射的值應該是函數爲該輸入列表返回的列表。

我的問題是:什麼是使用任意對象列表作爲Groovy映射關鍵字的最佳方式?我想我可以遍歷地圖中的所有鍵,並逐項比較每個列表(地圖的鍵)。但是,這種氣味,我認爲應該有一個更好,更快的方式。

任何想法?

回答

0

所以我結束了對輸入參數列表的調用hashCode()。好的是,即使對於不同的列表,只要它們的內容相同,我也可以獲得相同的散列值。這正是我想要的,我認爲這很合理。

+0

這可能會產生問題。不保證'hashCode'會相同。 [這個測試總是失敗](http://paste.ubuntu.com/7170363/)。 – dmahapatro

+0

是的,我知道列表的順序很重要。但在我的情況下,這很好,訂單不會改變。如果可以的話,也可以讓它緩存兩次... – Matthias

2

對於Groovy 2.2.x,可以使用@Memoized AST來進行內部緩存的方法。

@groovy.transform.Memoized 
List getMeList(List params) { 
    println "params passed $params" 
    params.reverse() 
} 

def paramsList = [1, 2, 4, 5, 6] 
getMeList(paramsList) 
getMeList(paramsList) 
getMeList(paramsList) 
getMeList(paramsList) 

def anotherList = ['a', 'b', 'c'] 
getMeList(anotherList) 
getMeList(anotherList) 
getMeList(anotherList) 
getMeList(anotherList) 

當它第一次調用方法和結果從緩存中得到了呼叫的其餘打印一次的差異便可以看出。

+0

哇,真是太棒了,謝謝。儘管有一個問題:我只需要在大多數情況下返回相同的列表,但不是全部。函數中確定緩存的值是否應該加以修改。那麼有沒有像有條件的「Memoized」? – Matthias

+0

只有註解可用的值是'maxCacheSize'和'protectedCacheSize',但是您可以讓該邏輯返回此方法以外的同一列表,並在調用這種僅執行一次繁重操作的memoized方法之前進行檢查。 – dmahapatro