Groovy在原语上非常慢

时间:2014-02-09 10:29:14

标签: performance groovy primitive

在我的应用程序中,每次使用Groovy都不能自动装箱吗?

以下代码......

public class SumTest {
    public static void main(String[] args) {
        long[] longs = new long[100000000];

        long nanoStart = System.nanoTime();
        long counter = 1;
        for (int i = 0; i < longs.length; i++) {
            longs[i] = counter++;
        }

        double msPop = (System.nanoTime() - nanoStart) / 1000000d;
        System.out.println("Time taken, population: " + msPop + "ms.");

        nanoStart = System.nanoTime();
        long sum = 0;
        for (int i = 0; i < longs.length; i++) {
            sum += longs[i];
        }
        double msSum = (System.nanoTime() - nanoStart) / 1000000d;
        System.out.println("Time taken, sum: " + msSum + "ms, total: " + (msPop + msSum) + "ms");
        System.out.println(" (sum: " + sum + ")");
    }
}

...从'.java'重命名为'.groovy'时展示了截然不同的运行时间:

爪哇:

Time taken, population: 94.793746ms.
Time taken, sum: 65.172605ms, total: 159.966351ms
 (sum: 5000000050000000)

Groovy的:

Time taken, population: 2233.995965ms.
Time taken, sum: 2203.64302ms, total: 4437.638985ms
 (sum: 5000000050000000)

..这是一个~30倍的差异。

当我在一个对象内部长时间(就像在我的真实代码中的情况一样)时,情况变得复杂

public class SumTest {
    static class Holder {
        long l;
        Holder(long l) { this.l = l; }
        long getL() { return l; }
    }

    public static void main(String[] args) {
        Holder[] longs = new Holder[100000000];

        long nanoStart = System.nanoTime();
        long counter = 1;
        for (int i = 0; i < longs.length; i++) {
            longs[i] = new Holder(counter++);
        }

        double msPop = (System.nanoTime() - nanoStart) / 1000000d;
        System.out.println("Time taken, population: " + msPop + "ms.");

        nanoStart = System.nanoTime();
        long sum = 0;
        for (int i = 0; i < longs.length; i++) {
            sum += longs[i].getL();
        }
        double msSum = (System.nanoTime() - nanoStart) / 1000000d;
        System.out.println("Time taken, sum: " + msSum + "ms, total: " + (msPop + msSum) + "ms");
        System.out.println(" (sum: " + sum + ")");
    }
}

运行时间(注意我在这里使用-Xms16384M -Xmx16384M运行):

爪哇

Time taken, population: 1083.784927ms.
Time taken, sum: 180.518991ms, total: 1264.3039179999998ms
 (sum: 5000000050000000)

Groovy的:

Time taken, population: 9816.007447ms.
Time taken, sum: 8685.506864ms, total: 18501.514311ms
 (sum: 5000000050000000)

..总共快了约15倍,但最重要的区别在于实际使用这些对象(用求和表示):~50x。

能以某种方式解决这个问题吗?当问题涉及原语和原语操作时,我是否可以哄骗Groovy不对每个涉及原语的操作进行自动操作?

1 个答案:

答案 0 :(得分:2)

(哇!奇怪,如何彻底地制定问题几乎立即导致答案?!)

修复:在课堂上写下@CompileStatic

Time taken, population: 1562.978726ms.
Time taken, sum: 183.388353ms, total: 1746.367079ms
 (sum: 5000000050000000)