静态块与静态方法 – 初始化静态字段
出于好奇,我测量了静态块和静态方法初始化器之间的性能。 首先,我在两个独立的java类中实现了上述方法,如下所示:
第一:
class Dummy { static java.util.List lista = new java.util.ArrayList(); 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 lista = new java.util.ArrayList(); 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())。 他们都做同样的事情,但为什么第一个慢? 我只能通过查看字节码来解释它,因为这是我第一次接触javap ; 我还不懂字节码。
我认为静态块版本比静态方法版本慢的原因可能是由于他们得到的JIT优化不同…
有关更多有趣信息,请参阅这篇有趣的文章: Java Secret:是否解释了静态块?
这是我猜测的原因:
您正在进行的初始化是创建足够的对象,导致一个或多个垃圾收集。
当从静态块调用初始化时,它在类初始化期间完成,而不是在简单方法执行期间完成。 在类初始化期间,即使堆的内容几乎相同,垃圾检测器也可能需要做更多的工作(例如,因为执行堆栈比较长的方法执行时)。
要测试这个,你可以尝试在你的java命令中添加-Xms200m或其他东西; 这应该消除了在初始化期间进行垃圾收集的需要。
- 单击JCheckBox时添加值
- 配置Java Socket以在断开连接时快速失败?
- 是否有另一种方法可以在Spring Boot中获取WebServiceTemplate而不是WebServiceGatewaySupport#getWebServiceTemplate()?
- 如何将Cross Origin资源共享与Spring MVC 4.0.0 RESTful Webservice集成
- Java是否有’@’字符来转义字符串引号?
- 是否可以使用Reflection迭代包内的所有类?
- Java和C#中的并行开发
- 如何在我的Lucene应用程序中使用ASCIIFoldingFilter?
- Javagenerics“捕获?”