Groovy:闭包明显慢于方法?

时间:2011-07-03 11:27:48

标签: performance groovy closures

在使用不同的排序算法时,我很惊讶Groovy关闭的表现非常糟糕。到目前为止我找不到一个好的答案,所以现在试试我的运气;)为什么Groovy闭包比传统方法慢得多?

这是一个显示性能差异的简单示例。它创建两个带有随机数的列表,并按相反的顺序对它们进行排序,测量排序时间。在我的机器和10k元素上,使用闭包只需 270ms ,使用Comparator实现只需 50ms

根据随机数的分布,时间稍有不同。我也尝试了Groovy 1.7.4和1.8.0,后者的性能稍好一些。但整体情况保持不变:关闭表现不佳。

我可以做些什么来改善闭合性能?当然除了不使用闭包;) 我是否遗漏了某些内容,或者如果性能有问题,是否应该在groovy中使用闭包?

def numberCount = 10000
def random = new Random()
def unorderedList1 = (1..numberCount).collect{random.nextInt()}
def unorderedList2 = (1..numberCount).collect{random.nextInt()}
def timeit = {String message, Closure cl->
    def startTime = System.currentTimeMillis()
    cl()
    def deltaTime = System.currentTimeMillis() - startTime
    println "$message: \ttime: $deltaTime"
}

timeit("compare using closure") {
    def comparator= [ compare: { a,b -> return b <=> a }] as Comparator
    unorderedList1.sort(comparator)
}

timeit("compare using method") {
    Comparator comparator = new MyComparator()
    unorderedList2.sort(comparator)
}

class MyComparator implements Comparator {
    int compare(a, b) {return b <=> a}
}

2 个答案:

答案 0 :(得分:4)

  

我可以做些什么来改善封闭性能?

<强>等待即可。 JDK7将添加一条新指令,称为invokeDynamic,可以从根本上提高JVM上动态语言的性能。

答案 1 :(得分:4)

在Ubuntu上使用OpenJDK 1.6(O6)和JDK 1.7(J7)进行Groovy 2.0.5更新。

我还添加了两个可能的实现:

  • 只提供了一个作为Comparator实现的闭包:
  • 使用@CompileStatic注释的方法:

    def numberCount = 10000
    def random = new Random()
    def unorderedList1 = (1..numberCount).collect{random.nextInt()}
    def unorderedList2 = (1..numberCount).collect{random.nextInt()}
    def unorderedList3 = (1..numberCount).collect{random.nextInt()}
    def unorderedList4 = (1..numberCount).collect{random.nextInt()}
    def timeit = {String message, Closure cl->
        def startTime = System.currentTimeMillis()
        cl()
        def deltaTime = System.currentTimeMillis() - startTime
        println "$message: \ttime: $deltaTime"
    }
    
    timeit("compare using map of closures") {
        def comparator= [ compare: { a,b -> return b <=> a }] as Comparator
        unorderedList1.sort(comparator)
    }
    
    timeit("compare using one closure") {
        def comparator= { a, b -> return b <=> a } as Comparator
        unorderedList2.sort(comparator)
    }
    
    timeit("compare using method") {
        Comparator comparator = new MyComparator()
        unorderedList3.sort(comparator)
    }
    
    timeit("compare using method with @CompileStatic") {
        Comparator comparator = new MyComparator2()
        unorderedList4.sort(comparator)
    }
    
    class MyComparator implements Comparator {
        int compare(a, b) {return b <=> a}
    }
    
    class MyComparator2 implements Comparator<Integer> {
        @groovy.transform.CompileStatic
        int compare(Integer a, Integer b) {return b <=> a}
    }
    
Groovy 2.0.5                groovy  groovyc 
                            O6      O6  J7
closure map                 258     499 146
one closure                 64      205 48
method                      29      37  32
@CompileStatic method       28      26  22

请注意,我没有安装使用JDK7编译的Groovy命令行(我自动安装了自己的OpenJDK6),因此缺少相应的列。