2

使用以下 Groovy 代码片段,我得到了一些意想不到的基准测试结果:

class A{
    def n(){
        return 1
    }
}
class B{
    def n(){
        return 2
    }
}
class C{
    def n(){
        return 3
    }
}
class D{
    def n(){
        return 4
    }
}

def bench(loops){
    def a = new A()
    def b = new B()
    def c = new C()
    def d = new D()
    def ret=0
    for(i=0; i<loops; i++){
        ret = ret + getN(a) + getN(b) + getN(c) + getN(d)
    }
    return ret
}

def getN(clazz){
    return clazz.n()
}

不得不说,我使用了编译好的类文件,并通过 Reflection API 调用了它。长话短说(不要问;)。对于第一印象,我使用了 10 轮 + 5 次热身和 10000 次循环。(junit-benchmark 框架)我的 JDK 是 Verison 1.7.0_09,我使用的是 Groovy 2.1。我在有和没有调用动态支持的情况下编译了代码 2 次。关键是,带有 invokedynamic 的基准测试比正常编译的基准花费的时间要长得多。我还用斐波那契数做了其他基准测试,其表现与预期的一样(indy 花了大约一半的时间)。

有人知道这里出了什么问题吗?

谢谢。

4

1 回答 1

1

我不是 Groovy 方面的专家,但我的印象是我在某处读过 Groovy 创建了类似“上帝类”的东西。该类包含出现在 Groovy 源代码中的所有方法,子类仅覆盖某些方法。制作这样的类允许通常的调用虚拟调用而不是动态查找。这可能是放缓的原因。

尝试对类进行一些运行时注入方法,以打破 Groovy 的静态分析并强制编译器输出动态查找代码。

于 2013-06-04T13:11:54.200 回答