Memoization
Memoization is an optimization technique that consists in storing the results of expensive function calls and returning the cached result whenever the function is called again with the same arguments.
There is an unlimited version, that will cache ever pair of (input arguments, return value) it will ever see; and a limited version, that will cache the last N input arguments seen and their results, using a LRU cache.
Memoization of methods:
import groovy.transform.Memoized
@Memoized
Number factorial(Number n) {
n == 0 ? 1 : factorial(n - 1)
}
@Memoized(maxCacheSize=1000)
Map fooDetails(Foo foo) {
// call expensive service here
}
Memoization of closures:
def factorial = {Number n ->
n == 0 ? 1 : factorial(n - 1)
}.memoize()
fooDetails = {Foo foo ->
// call expensive service here
}.memoizeAtMost(1000)
The Wikipedia page has extensive information on the uses of Memoization in Computer Science. I will just point out one simple practical use.
Deferring the initialization of a constant to the last possible moment
Sometimes you have a constant value that cannot be initialized at class definition or creation time. For example, the constant expression may make use of another constant or a method from a different class, which will be plugged in by something else (Spring or such) after the initialization of your class.
In this case, you can convert your constant into a getter and decorate it with @Memoized
. It will only be computed once, the first time it's accessed, and then the value cached and reused:
import groovy.transform.Memoized
@Memoized
def getMY_CONSTANT() {
// compute the constant value using any external services needed
}