Groovy中那些神奇註解之Memoized
阿新 • • 發佈:2018-12-04
PS:強烈推薦Groovyr官方文件,相當的詳細,地址:http://www.groovy-lang.org/documentation.html,不用擔心是英文,有點程式碼經驗的,一看示例程式碼就知道是什麼意思了。
好了,閒話少說,第一個註解:Memoized
Memoized的全稱是:groovy.transform.Memoized,在groovy.transform包下,有很多相關的註解,可以好好了解一下
至於Memoized的作用,看名字就很明白了,就是“記住”,沒錯,就是把方法的執行結果快取起來,下次呼叫時,如果引數一樣,那方法就不再計算而是直接返回結果了,該註解對於那些引數範圍比較少,並且只要引數一定,那麼結果肯定也是唯一的方法,有著很好的加速效果。
舉個最簡單,但是個人覺得最能體現Memoized效果的例子,大家應該都實現過用遞迴方式實現斐波那契(fibnacci)數列吧,但是純粹的不加優化的遞迴方式是相當相當的沒效率的,在我的電腦上,計算到40左右,電腦就有點跑不動了,看看程式碼:
class Fibnacci{
long total = 0 //用來統計一共計算了多少次
int n //計算多少的數列
public Fibnacci(int n){
this.n = n
}
def fibnacci_1(n){
total ++
n < 2 ? 1 : fibnacci_1(n-1) + fibnacci_1(n-2)
}
@groovy.transform.Memoized
def fibnacci_2(n){
total ++
n < 2 ? 1 : fibnacci_2(n-1) + fibnacci_2(n-2)
}
//測試不使用Memoized
def runWithoutMem(){
long start = System.currentTimeMillis()
total = 0
def val = fibnacci_1(n)
long time = System.currentTimeMillis() - start
println "未使用Memoized,${n}的Fibnacci值是${val},共用時${time}毫秒,函式呼叫共${total}次"
}
//測試使用Memoized
def runWithMem(){
long start = System.currentTimeMillis()
total = 0
def val = fibnacci_2(n)
long time = System.currentTimeMillis() - start
println "使用Memoized,${n}的Fibnacci值是${val},共用時${time}毫秒,函式呼叫共${total}次"
}
}
def fib = new Fibnacci(40)
fib.runWithoutMem()
fib.runWithMem()
fibnacci_1和fibnacci_2方法實現是完全一樣的,唯一的不一致就是一個加上了註解,同時我在類裡面加上了一個變數total,來統計方法一共被呼叫了多少次,把上面的程式碼複製到Groovy自帶的GroovyConsole程式中(神器呀),直接就可以執行,看看結果:
Result: 未使用Memoized,40的Fibnacci值是165580141,共用時6040毫秒,函式呼叫共331160281次
使用Memoized,40的Fibnacci值是165580141,共用時4毫秒,函式呼叫共41次
結果很驚人吧,因為Memoized把計算的結果快取下來了,如果引數一樣就不用再重複計算了,所以效率自然大大提高,這就好像我們用陣列方法來實現fibnacci從而提高效率原理是差不多的,不過這樣小小的一個註解,可以少寫好多程式碼省不少事了:)
親測 有效