出于好奇,我测量了静态块和静态方法初始化器之间的性能。首先,我在两个独立的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);
}
}
然后我执行了this小批量脚本来测量它100次并将值放在一个文件中。 batchFile.bat First Second dum.res.txt
之后,我写了this段代码来计算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())。 他们都做同样的事情,但为什么第一个慢?我只能通过查看字节码来解释它,因为这是我第一次触摸 javap ;我还不懂字节码。
答案 0 :(得分:2)
我认为静态块版本比静态方法版本慢的原因可能是由于它们得到的JIT优化不同......
有关更多有趣信息,请参阅此有趣文章:Java Secret: Are static blocks interpreted?
答案 1 :(得分:2)
以下是我猜测的原因:
您正在进行的初始化是创建足够的对象,导致一个或多个垃圾收集。
当从静态块调用初始化时,它在类初始化期间完成,而不是在简单方法执行期间完成。在类初始化期间,即使堆的内容几乎相同,垃圾检测器可能还有一些工作要做(例如,因为执行堆栈比较长),即使堆的内容几乎相同。
要测试这个,你可以尝试在你的java命令中添加-Xms200m或其他东西;这应该消除了在初始化期间垃圾收集的需要。