静态块与静态方法-初始化静态字段

8

出于好奇心,我测量了静态块和静态方法初始化之间的性能差异。首先,我在两个不同的Java类中实现了上述方法,如下所示:

第一种方法:

class Dummy {
    static java.util.List<Integer> lista = new java.util.ArrayList<Integer>();
    static {
        for(int i=0; i < 1000000; ++i) {
            lista.add(new Integer(i));
        }
    }
}

public class First {
    public static void main(String[] args) { 
        long st = System.currentTimeMillis();
            Dummy d = new Dummy();
        long end = System.currentTimeMillis() - st;
        System.out.println(end);    
    }
}

第二点:

class Muddy {
    static java.util.List<Integer> lista = new java.util.ArrayList<Integer>();
    public static void initList() {
        for(int i=0; i < 1000000; ++i) {
            lista.add(new Integer(i));
        }
    }
}

public class Second {
    public static void main(String[] args) { 
        long st = System.currentTimeMillis();
            Muddy.initList();
            Muddy m = new Muddy();
        long end = System.currentTimeMillis() - st;
        System.out.println(end);    
    }
}

我执行了这个小的批处理脚本来测量100次并将值存入文件。batchFile.bat First Second dum.res.txt 之后,我写了这段代码来计算Dummy和Muddy的平均值和标准差。
这是我得到的结果:
First size: 100 Second size: 100
First       Sum: 132    Std. deviation: 13
Second      Sum: 112    Std. deviation: 9

在我的其他电脑上也是一样的...每次测试都是这样。

现在我在想,为什么会这样呢?我检查了字节码,发现Second.class在System.currentTimeMillis()调用之间有一个额外指令(调用静态initList())。它们都做同样的事情,但为什么First比Second慢呢?我不能仅仅通过查看字节码就推出结论,因为这是我第一次接触javap;我还不理解字节码。


尝试在调用批处理脚本时颠倒第一和第二个参数,看看结果如何 :) - antlersoft
指令数量与指令执行时间无关(比如让你开车穿过城镇和穿过整个国家 - 除非你住在列支敦士登之类的地方)。它们是完全相同的指令吗?我很怀疑。另外,顺便说一下,即使第二个版本更快,我也会犹豫使用它 - 它依赖于对initList()的调用,这是我从不指望的事情。 - Clockwork-Muse
@antlersoft 它返回相同的结果。已经测试过了。 - Mechkov
@X-Zero 我认为他们是。但是,你关于第二个的看法是正确的。我也不会将其用于这样的目的。 - nullpotent
@AljoshaBre - 你不能只考虑FirstSecond之间的指令;那DummyMuddy呢? - Clockwork-Muse
显示剩余3条评论
2个回答

2

2
这是我对此问题的猜测:
你所做的初始化正在创建足够多的对象,这可能导致一个或多个垃圾回收操作。
当从静态块调用初始化时,它是在类初始化期间完成的,而不是在简单方法执行期间完成的。在类初始化期间,垃圾检测器可能需要更多的工作(例如,执行堆栈更长),即使堆的内容几乎相同。
为了测试这一点,你可以尝试在java命令中添加-Xms200m或其他内容;这应该消除你所做的初始化过程中进行垃圾回收的需要。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接