Groovy集合关于空间/时间的性能注意事项 [英] Groovy collections performance considerations regarding space/time

查看:58
本文介绍了Groovy集合关于空间/时间的性能注意事项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与普通Java for循环相比,Groovys收集方法(关于空间(!)和时间)的性能如何?

What is the performance of Groovys collection methods (regarding space(!) and time) in comparison to plain Java for-loops?

例如以下用例:

  • sum()与带变量的for循环
  • each()与带变量的for循环
  • inject()与带变量的for循环
  • collect()与带有临时集合的for循环
  • findAll()与带有临时集合的for循环
  • find()与带变量的for循环

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

So, considering those results, is it advisable to use for-loops over Groovy-collection-methods in critical environments (eg. Grails-WebApp)? Are there resources regarding Groovy/Grails performance (optimization)?

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

Using this GBench test I got the following results for CPU-time:

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

推荐答案

有趣的基准. sum()变慢也就不足为奇了.实施方式如下:

Interesting benchmark. No surprise that sum() is slower. Here's how implementation looks like:

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;
}

如您所见,它必须是通用的,并且使用元编程.结果是更大的时间成本.

As You can see it must be generic and uses meta programming. The result is bigger time cost.

您粘贴的基准测试结果清晰且具有自我描述性.如果您确实需要更好的性能,似乎更好的主意是使用for循环.

The results of the benchmark You pasted are clear and pretty self descriptive. If You really need better performance it seems that better idea is to use for loops.

这篇关于Groovy集合关于空间/时间的性能注意事项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆