Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 29d6d73

Browse files
Merge pull request #76 from AcceptedBoy/master
add->efficiency-of-java-double-brace-initialization.md
2 parents 9ca39a5 + af78212 commit 29d6d73

File tree

1 file changed

+202
-0
lines changed

1 file changed

+202
-0
lines changed
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
## "Double Brace Initialization"的效率问题
2+
3+
#### 问题
4+
5+
`Double Brace Initialization`是java的隐藏特性,它有着如下诱人的语法:
6+
7+
```java
8+
Set<String> flavors = new HashSet<String>() {{
9+
add("vanilla");
10+
add("strawberry");
11+
add("chocolate");
12+
add("butter pecan");
13+
}};
14+
```
15+
16+
但是,这个特性听说不是很高效率,是否要限制一次性使用?
17+
18+
#### 回答
19+
20+
当我使用匿名内部类时出现了如下的问题:
21+
22+
```Auto
23+
2009年05月27日 16:35 1,602 DemoApp21ドル.class
24+
2009年05月27日 16:35 1,976 DemoApp210ドル.class
25+
2009年05月27日 16:35 1,919 DemoApp211ドル.class
26+
2009年05月27日 16:35 2,404 DemoApp212ドル.class
27+
2009年05月27日 16:35 1,197 DemoApp213ドル.class
28+
29+
/* snip */
30+
31+
2009年05月27日 16:35 1,953 DemoApp230ドル.class
32+
2009年05月27日 16:35 1,910 DemoApp231ドル.class
33+
2009年05月27日 16:35 2,007 DemoApp232ドル.class
34+
2009年05月27日 16:35 926 DemoApp233ドル1ドル1ドル.class
35+
2009年05月27日 16:35 4,104 DemoApp233ドル1ドル.class
36+
2009年05月27日 16:35 2,849 DemoApp233ドル.class
37+
2009年05月27日 16:35 926 DemoApp234ドル1ドル1ドル.class
38+
2009年05月27日 16:35 4,234 DemoApp234ドル1ドル.class
39+
2009年05月27日 16:35 2,849 DemoApp234ドル.class
40+
41+
/* snip */
42+
43+
2009年05月27日 16:35 614 DemoApp240ドル.class
44+
2009年05月27日 16:35 2,344 DemoApp25ドル.class
45+
2009年05月27日 16:35 1,551 DemoApp26ドル.class
46+
2009年05月27日 16:35 1,604 DemoApp27ドル.class
47+
2009年05月27日 16:35 1,809 DemoApp28ドル.class
48+
2009年05月27日 16:35 2,022 DemoApp29ドル.class
49+
```
50+
51+
这是在我的一个简单应用中所产生的类信息。在这个应用中,使用了大量的匿名内部类,这些类会被单独地编译成`class`文件。
52+
53+
`Double Brace Initialization`是一个带有实例初始化块的匿名内部类。这就意味着每一个新的类的产生都会执行一次实例块,这样的目的通常是为了创建一个简单的对象。
54+
55+
java虚拟机在使用类之前需要去读取其classes信息,然后执行字节码校验等流程。所以为了保存这些`class`文件,所需要的磁盘空间会增大。
56+
57+
这个可以说是`Double Brace Initialization`的开销。所以尽量不要过分使用。
58+
59+
---
60+
61+
在java的介绍中,`Double Brace Initialization`有着如下的写法:
62+
63+
```java
64+
List<String> list = new ArrayList<String>() {{
65+
add("Hello");
66+
add("World!");
67+
}};
68+
```
69+
70+
看起来像是java的隐藏特性,其实它只是下面代码的一个重写:
71+
72+
```java
73+
List<String> list = new ArrayList<String>() {
74+
75+
// 实例初始化块
76+
{
77+
add("Hello");
78+
add("World!");
79+
}
80+
};
81+
```
82+
83+
所以,它只是在匿名内部类中加上了实例初始化块而已。
84+
85+
---
86+
87+
Joshua Bloch希望以后的集合代码能够像这样简介:
88+
89+
```java
90+
List<Integer> intList = [1, 2, 3, 4];
91+
92+
Set<String> strSet = {"Apple", "Banana", "Cactus"};
93+
94+
Map<String, Integer> truthMap = { "answer" : 42 };
95+
```
96+
97+
但目前还没有这样的语法。
98+
99+
---
100+
101+
<strong>实践</strong>
102+
103+
做一个简单的试验:创建1000个带着`"Hello"``"World!"`元素的`ArrayList`
104+
105+
* 方法1:Double Brace Initialization
106+
107+
```
108+
List<String> l = new ArrayList<String>() {{
109+
add("Hello");
110+
add("World!");
111+
}};
112+
```
113+
114+
* 方法2:初始化`ArrayList`并调用`add`方法
115+
116+
```java
117+
List<String> l = new ArrayList<String>();
118+
l.add("Hello");
119+
l.add("World!");
120+
```
121+
122+
我修改了java的源文件使之能够为每种上述方法分别创建出1000个实例
123+
124+
* 方法1的测试
125+
126+
```java
127+
class Test1 {
128+
public static void main(String[] s) {
129+
long st = System.currentTimeMillis();
130+
131+
List<String> l0 = new ArrayList<String>() {{
132+
add("Hello");
133+
add("World!");
134+
}};
135+
136+
List<String> l1 = new ArrayList<String>() {{
137+
add("Hello");
138+
add("World!");
139+
}};
140+
141+
/* snip */
142+
143+
List<String> l999 = new ArrayList<String>() {{
144+
add("Hello");
145+
add("World!");
146+
}};
147+
148+
System.out.println(System.currentTimeMillis() - st);
149+
}
150+
```
151+
152+
* 方法2的测试
153+
154+
```java
155+
class Test2 {
156+
public static void main(String[] s) {
157+
long st = System.currentTimeMillis();
158+
159+
List<String> l0 = new ArrayList<String>();
160+
l0.add("Hello");
161+
l0.add("World!");
162+
163+
List<String> l1 = new ArrayList<String>();
164+
l1.add("Hello");
165+
l1.add("World!");
166+
167+
/* snip */
168+
169+
List<String> l999 = new ArrayList<String>();
170+
l999.add("Hello");
171+
l999.add("World!");
172+
173+
System.out.println(System.currentTimeMillis() - st);
174+
}
175+
}
176+
```
177+
178+
然后得出了下面的测试时间:
179+
180+
```Auto
181+
Test1 Times (ms) Test2 Times (ms)
182+
---------------- ----------------
183+
187 0
184+
203 0
185+
203 0
186+
188 0
187+
188 0
188+
187 0
189+
203 0
190+
188 0
191+
188 0
192+
203 0
193+
```
194+
195+
从上面我们可以看到,`Double Brace Initialization`平均时间花费了190ms左右。
196+
同时,另外一种方法平均只用了0ms。
197+
198+
所以,在第一个方法测试程序中,即`Double Brace Initialization`产生了1000个`class`文件。
199+
200+
## StackOverflow地址
201+
202+
[http://stackoverflow.com/questions/924285/efficiency-of-java-double-brace-initialization](http://stackoverflow.com/questions/924285/efficiency-of-java-double-brace-initialization)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /