Groovy中那些神奇註解之Memoized

臨近年關手頭比較閒,去看了一下Groovy的官方文檔,才發現原來Groovy中帶了那麼多的註解,不少註解帶來的效果,有時候讓人感受「這不是在變魔法吧」。html

我的很喜歡Groovy,寫不成Ruby,Groovy同樣讓我很愉悅。惋惜在國內Groovy實在沒什麼人氣,連個像樣的官方站都沒有,或許是由於喜歡腳本的都在寫ruby,python,寫Java的又對他不屑一顧?python

接下來的一系列文章,就只介紹一些我我的以爲很好用,在開發中用到機會會比較多的註解。數組

PS:強烈推薦Groovyr官方文檔,至關的詳細,地址:http://www.groovy-lang.org/documentation.html,不用擔憂是英文,有點代碼經驗的,一看示例代碼就知道是什麼意思了。緩存

好了,閒話少說,第一個註解:Memoizedruby

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程序中(神器呀),直接就能夠運行,看看結果:

結果很驚人吧,由於Memoized把計算的結果緩存下來了,若是參數同樣就不用再重複計算了,因此效率天然大大提升,這就好像咱們用數組方法來實現fibnacci從而提升效率原理是差很少的,不過這樣小小的一個註解,能夠少寫好多代碼省很多事了:)

好了,就到這裏了,休息,休息一下this

相關文章
相關標籤/搜索