Methods 在Groovy中记忆成员方法
我有一个方法,它是一个简单的方法,需要一段时间才能运行。我想记住这个方法,以便后续调用更快。我可以在Groovy的文档中看到,您可以通过以下方式记忆闭包:Methods 在Groovy中记忆成员方法,methods,groovy,memoization,Methods,Groovy,Memoization,我有一个方法,它是一个简单的方法,需要一段时间才能运行。我想记住这个方法,以便后续调用更快。我可以在Groovy的文档中看到,您可以通过以下方式记忆闭包: foo={…}.memoize() 但是,我找不到一种方法来记忆成员方法。有什么方法可以做到这一点吗?我不知道有什么方法可以像记忆闭包一样直接记忆方法 如果该方法没有收到任何参数(因此返回值总是相同的,因为它是纯的),您可以通过将返回值存储在成员属性中来进行记忆。这种技术在Ruby中非常常见,通常采用defsome_方法的形式@值| |=计算
foo={…}.memoize()
但是,我找不到一种方法来记忆成员方法。有什么方法可以做到这一点吗?我不知道有什么方法可以像记忆闭包一样直接记忆方法 如果该方法没有收到任何参数(因此返回值总是相同的,因为它是纯的),您可以通过将返回值存储在成员属性中来进行记忆。这种技术在Ruby中非常常见,通常采用
defsome_方法的形式@值| |=计算值;结束
。将其转换为Groovy,您可以执行以下操作:
class Computer {
private answer
def getAnswer() {
answer = answer ?: computeAnswer()
}
private computeAnswer() {
println "Computing the Answer to the Ultimate Question of Life, the Universe, and Everything"
42
}
}
def c = new Computer()
println c.answer
println c.answer
输出为:
计算生命、宇宙和一切终极问题的答案
42
42
因此,备忘录起了作用:)
如果不想定义额外的方法,还可以编写getAnswer
方法,如下所示:
def getAnswer() {
if (answer != null) return answer
println "Computing the Answer to the Ultimate Question of Life, the Universe, and Everything"
answer = 42
}
现在,如果该方法确实收到任何参数,那么以这种方式实现记忆将非常麻烦。相反,您可以从要记忆的方法调用记忆的闭包:
class Calculator {
def sum(a, b) {
memoizedSum(a, b)
}
private memoizedSum = { a, b ->
println "Computing the sum of $a and $b"
a + b
}.memoize()
}
def c = new Calculator()
println c.sum(4, 7)
println c.sum(4, 7)
println c.sum(4, 2)
输出为:
计算4和7之和
11
11
计算4和2之和
6.
编辑:
在Groovy 2.2.X中,将有一个名为@Memoized
的新AST转换,它将为您实现这一点
import groovy.transform.Memoized
class Woo {
@Memoized
def sum( int a, int b ) {
Thread.sleep( 1000 )
a + b
}
}
new Woo().with {
println new Date()
println sum( 1, 2 )
println new Date()
println sum( 1, 2 )
println new Date()
}
原始答案 另一种选择是编写某种AST转换,允许您使用
@Memoize
注释方法,并为您完成memoization
我可以找到两个例子,一个,另一个,基本上通过操纵AST使其看起来像epidemian答案的第二部分
由于您可能需要多个参数,我选择epidemian的第二种方法。然而,编写AST转换可能是一个有趣的实验/附带项目
如果做得好,我也可以回到Groovy核心源代码(为了名声和荣耀):-)是的,我实际上正在尝试重构使用
兽人策略的代码(你第一个例子的另一个名字)。它需要一个参数,但我使用映射缓存它。您的第二部分与我要查找的内容更接近。假设没有人给出更直接的答案,我可能会这么认为。我可能很愚蠢,但为什么你不能这么做:def sum={a,b->..}。memoize()很酷的答案!编写@Memoize AST转换确实是一个很酷的实验。我喜欢你发布的第二个链接上的代码,这个AstBuilder看起来像sugoi=黛雅,这正是我所希望的。也许我可以在这方面做些修改。更新了我的答案,因为这个注释将出现在Groovy 2.2.x:-)