关于空间/时间的Groovy集合性能考虑因素

时间:2014-06-03 07:45:13

标签: java performance grails optimization groovy

与普通Java for循环相比,Groovys集合方法(关于空间(!)和时间)的性能是什么?

例如,对于这个用例:

  • sum()与for-loop with variable
  • 每个()与for循环的变量
  • inject()与for-loop with variable
  • 使用临时收集的collect()与for循环
  • findAll()与for-loop with temporary collection
  • find()vs. for-loop with variable

因此,考虑到这些结果,是否建议在关键环境中使用for循环而不是Groovy-collection-methods(例如Grails-WebApp)?是否有关于Groovy / Grails性能(优化)的资源?


使用此GBench测试,我得到了以下CPU时间结果:

                 user  system      cpu     real

forLoop       2578777      67  2578844  2629592
forEachLoop   2027941      47  2027988  2054320
groovySum     3946137      91  3946228  3958705
groovyEach    4703000       0  4703000  4703000
groovyInject  4280792     108  4280900  4352287



import groovyx.gbench.BenchmarkBuilder

def testSize = 10000
def testSet = (0..testSize) as Set


def bm = new BenchmarkBuilder().run {

'forLoop' {
    def n = 0
    for(int i = 0; i<testSize; i++) {
        n += i
    }
    return n
}

'forEachLoop' {
    def n = 0
    for(int i in testSet) {
        n += i
    }
    return n
}

'groovySum' {
    def n = testSet.sum()
    return n
}

'groovyEach' {
    def n = 0
    testSet.each { n + it }
    return n
}

'groovyInject' {
    def n = testSet.inject(0) { el, sum -> sum + el }
    return n
}
}
bm.prettyPrint()

1 个答案:

答案 0 :(得分:15)

有趣的基准。毫不奇怪sum()更慢。这是实现的样子:

private static Object sum(Iterable self, Object initialValue, boolean first) {
        Object result = initialValue;
        Object[] param = new Object[1];
        for (Object next : self) {
            param[0] = next;
            if (first) {
                result = param[0];
                first = false;
                continue;
            }
            MetaClass metaClass = InvokerHelper.getMetaClass(result);
            result = metaClass.invokeMethod(result, "plus", param);
        }
        return result;
}

正如您所看到的,它必须是通用的并使用元编程。结果是更大的时间成本。

您粘贴的基准测试结果清晰且非常具有自我描述性。如果你真的需要更好的性能,似乎更好的想法是使用for循环。