问题描述
与普通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集合关于空间/时间的性能注意事项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!