Methods 在Groovy中记忆成员方法

Methods 在Groovy中记忆成员方法,methods,groovy,memoization,Methods,Groovy,Memoization,我有一个方法,它是一个简单的方法,需要一段时间才能运行。我想记住这个方法,以便后续调用更快。我可以在Groovy的文档中看到,您可以通过以下方式记忆闭包: foo={…}.memoize() 但是,我找不到一种方法来记忆成员方法。有什么方法可以做到这一点吗?我不知道有什么方法可以像记忆闭包一样直接记忆方法 如果该方法没有收到任何参数(因此返回值总是相同的,因为它是纯的),您可以通过将返回值存储在成员属性中来进行记忆。这种技术在Ruby中非常常见,通常采用defsome_方法的形式@值| |=计算

我有一个方法,它是一个简单的方法,需要一段时间才能运行。我想记住这个方法,以便后续调用更快。我可以在Groovy的文档中看到,您可以通过以下方式记忆闭包:

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:-)