简体   繁体   English

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

[英]Static block vs static method - initializing static fields

Out of curiosity, I measured the performance between static block and static method initializer. 出于好奇,我测量了静态块和静态方法初始化程序之间的性能。 First, I implemented the above mentioned methods in two separate java classes, like so: 首先,我在两个单独的java类中实现了上述方法,如下所示:

First: 第一:

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);    
    }
}

Second: 第二:

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);    
    }
}

Then I executed this little batch script to measure it 100 times and put the values in a file. 然后,我执行了这个小批处理脚本以对其进行100次测量,并将值放入文件中。 batchFile.bat First Second dum.res.txt

After that, I wrote this piece of code to calculate mean value and standard deviation of Dummy's and Muddy's measured values. 之后,我编写了这段代码来计算Dummy和Muddy的测量值的平均值和标准偏差。

This is the result that I've got: 这是我得到的结果:

First size: 100 Second size: 100
First       Sum: 132    Std. deviation: 13
Second      Sum: 112    Std. deviation: 9

And it is similar on my other machines...every time I test it. 而且在其他机器上也是如此...每次测试时。

Now I'm wondering, why is it so? 现在我想知道,为什么会这样呢? I checked the bytecode and Second.class has one instruction more (call to static initList()) between calls to System.currentTimeMillis(). 我检查了字节码,在对System.currentTimeMillis()的调用之间,Second.class还有一条指令(对static initList()的调用)。 They both do the same thing, but why is the First one slower? 他们俩都做同样的事情,但是为什么第一个要慢一些? I can't really reason it out just by looking at the bytecode, since this was my first time touching javap ; 我真的不能仅仅通过查看字节码来推断原因,因为这是我第一次接触javap I don't understand bytecode yet. 我还不了解字节码。

I think that the reason why the static block version is slower than the static method version could be due to the different JIT optimization that they get ... 我认为静态块版本比静态方法版本慢的原因可能是由于它们获得了不同的JIT优化...

See this interesting article for more interesting information : Java Secret: Are static blocks interpreted? 请参阅此有趣的文章以获取更多有趣的信息: Java机密:是否解释静态块?

Here's my guess as to the reason for this: 这是我对此的猜测:

The initialization you are doing is creating enough objects that it is causing one or more garbage collections. 您正在执行的初始化操作正在创建足以导致一个或多个垃圾回收的对象。

When the initialization is called from the static block, it is done during the class initialization rather than during simple method execution. 从静态块调用初始化时,它是在类初始化期间完成的,而不是在简单方法执行期间完成的。 During class initialization, the garbage detector may have a little more work to do (because the execution stack is longer, for example) than during simple method execution, even though the contents of the heap are almost the same. 在类初始化期间,即使堆的内容几乎相同,垃圾检测程序也可能比简单方法执行期间要做更多的工作(例如,因为执行堆栈更长)。

To test this, you could try adding -Xms200m or something to your java commands; 为了测试这一点,您可以尝试在Java命令中添加-Xms200m或其他内容。 this should eliminate the need to garbage collect during the initialization you are doing. 这应该消除了您在初始化期间进行垃圾回收的需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM