Closure Caching For Increased Performance (.memoize())

29 / Dec / 2011 by Kushal Likhi 2 comments

Well This is something awesome and can increase the performance of the project when used wisely. using the groovy .memoize() we can ask closures to perform kind of caching. This can boost up the performance of the system.

 

_

Note: This feature is available in groovy 1.8+

Well Let me Explain this Using Examples

Now suppose i have a function “distance” which calculates distance between two points.
Hence for it instead of writing a function(Method) lets write a closure for it.

        def distance = {x1, y1, x2, y2 ->
            sleep(200)  //just to add a delay for demo purposes
            Math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
        }

       //To Call It 5 Times 
       5.times {
            def t1 = System.currentTimeMillis()
            println distance(100, 20, 400, 10)
            println "took: ${System.currentTimeMillis() - t1} milliseconds to execute"
        }

Now if we will Run this the Output will be as follows:

300.1666203960727
took: 201 milliseconds to execute
300.1666203960727
took: 200 milliseconds to execute
300.1666203960727
took: 201 milliseconds to execute
300.1666203960727
took: 201 milliseconds to execute
300.1666203960727
took: 201 milliseconds to execute

Each time this closure is called all statements are executed again and hence re-computation. But if set of inputs are same then technically output should be same. hence a type of caching will help.
Also if several users are acessing the app then for each user if something is done again and again though the inputs are same then that is again a overhead, this issue can also be solved by memoizeing. :)

Now lets Do it with .memoize()

        def distance = {x1, y1, x2, y2 ->
            sleep(200)  //just to add a delay for demo purposes
            Math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
        }.memoize() //Note now closure is memoized 

       //To Call It 5 Times 
       5.times {
            def t1 = System.currentTimeMillis()
            println distance(100, 20, 400, 10)
            println "took: ${System.currentTimeMillis() - t1}"
        }

Now the result is:

300.1666203960727
took: 202 milliseconds to execute
300.1666203960727
took: 1 milliseconds to execute
300.1666203960727
took: 1 milliseconds to execute
300.1666203960727
took: 0 milliseconds to execute
300.1666203960727
took: 0 milliseconds to execute

We can definitely see the difference between time taken to execute.
AND HURRAY, ALL REPETITIVE CALLS WITH SAME INPUT DATA ARE NOW CACHED AND HENCE INCREASED PERFORMANCE.

 

Hope it helped
Regards
Kushal Likhi

FOUND THIS USEFUL? SHARE IT

comments (2)

Leave a comment -