Groovy收集关于空间/时间的性能考虑 [英] Groovy collections perfomance considerations regarding space/time

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

问题描述

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



例如,对于这种用例:


  • sum()与for循环变量

  • each()vs. for-循环与变量

  • inject()与for循环与变量

  • collect()与for-loop与临时集合

  • findAll()与带临时集合的for-loop

  • find()与for循环与变量



因此,考虑到这些结果,对于关键环境中的Groovy-collection-methods(例如Grails-WebApp)使用for-loops是可取的吗?是否有关于Groovy / Grails性能(优化)的资源?






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

 用户系统cpu真实
$ b $循环2578777 67 2578844 2629592
forEachLoop 2027941 47 2027988 2054320
groovySum 3946137 91 3946228 3958705
groovyEach 4703000 0 4703000 4703000
groovyInject 4280792 108 4280900 4352287



导入groovyx.gbench。 BenchmarkBuilder
$ b $ def testSize = 10000
def testSet =(0..testSize)as Set


bm = new BenchmarkBuilder()。run {

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

$ b $ forEachLoop'{
def n = 0
for(int i in testSet){
n + = i
}
返回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 + el}
return n
}
}
bm.prettyPrint()


解决方案

有趣的基准。毫不奇怪, 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;
继续;
}
MetaClass metaClass = InvokerHelper.getMetaClass(result);
result = metaClass.invokeMethod(result,plus,param);
}
返回结果;





$ b

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

您粘贴的基准测试结果是清晰自然的描述。如果你真的需要更好的表现,似乎更好的想法是使用作为循环。


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

Eg for this use cases:

  • sum() vs. for-loop with variable
  • each() vs. for-loop with variable
  • inject() vs. for-loop with variable
  • collect() vs. for-loop with temporary collection
  • findAll() vs. for-loop with temporary collection
  • find() vs. for-loop with variable

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


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

解决方案

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.

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天全站免登陆