下面的代码是我用来比较代码优化前后的性能

 

1. import
2. import
3. import
4. import
5. import
6. import
7. import
8.  
9. public class
10.  
11. public static void
12.  
13. /* 
14.          * 避免在循环条件中使用复杂表达式 
15.          * @author yifangyou 
16.          * @since 2011-08-16 09:35:00 
17.          *  
18.          */
19. //      test0(); 
20. /* 
21.          * 如果只是查找单个字符的话,用charAt()代替startsWith() 
22.          * @author yifangyou 
23.      * @since 2011-08-16 09:35:00 
24.          */
25. //      test1(); 
26.  
27.  
28. /* 
29.          * 能够使用移位的乘除,最好用移位 
30.          * @author yifangyou 
31.      * @since 2011-08-16 09:35:00 
32.          */
33. //       test2(); 
34.  
35. /* 
36.          * 只有一个字符的字符串拼接,用''代替"" 
37.          * @author yifangyou 
38.      * @since 2011-08-16 09:35:00 
39.          */
40. //       test3(); 
41.  
42. /** 
43.          * try catch最好不要放在循环里 
44.          * @author yifangyou 
45.      * @since 2011-08-16 09:35:00 
46.          */
47. //       test4(); 
48.  
49. /** 
50.          * switch的实现 map比较稳定,if最慢,switch在数量少于10个时最快,随着数量增加下降厉害 
51.          * @author yifangyou 
52.      * @since 2011-08-16 09:35:00 
53.          */
54. //      test5(); 
55.  
56. /* 
57.          * 对于常量字符串,用'String' 代替 'StringBuffer' ,节省空间,节省时间 
58.          * @author yifangyou 
59.      * @since 2011-08-16 09:35:00 
60.          */
61. //      test6(); 
62. /* 
63.          * 用'StringTokenizer' 代替 'indexOf()' 和'substring()' 
64.          * 字符串的分析在很多应用中都是常见的。使用indexOf 
65.          * ()和substring()来分析字符串容易导致StringIndexOutOfBoundsException。 
66.          * 而使用StringTokenizer类来分析字符串则会容易一些,效率也会低一些。 
67.          * @author yifangyou 
68.      * @since 2011-08-16 09:35:00 
69.          */
70. //       test7(); 
71.  
72. /* 
73.          * 不要在循环体中实例化变量 在循环体中实例化临时变量将会增加内存消耗 
74.          * @author yifangyou 
75.      * @since 2011-08-16 09:35:00 
76.          */
77. //       test8(); 
78. /* 
79.          * 确定 StringBuffer的容量 
80.          * StringBuffer的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小 
81.          * ,就会重新分配内存,创建一个更大的数组,并将原先的数组复制过来,再丢弃旧的数组。在大多数情况下,你可以在创建 
82.          * StringBuffer的时候指定大小,这样就避免了在容量不够的时候自动增长,以提高性能。 
83.          * @author yifangyou 
84.      * @since 2011-08-16 09:35:00 
85.          */
86. //       test9(); 
87. /* 
88.          * 尽可能的使用栈变量 
89.          *  
90.          * 如果一个变量需要经常访问,那么你就需要考虑这个变量的作用域了。static? 
91.          * local?还是实例变量?访问静态变量和实例变量将会比访问局部变量多耗费2-3个时钟周期。 
92.          * @author yifangyou 
93.      * @since 2011-08-16 09:35:00 
94.          */
95. //      test10(); 
96. /** 
97.          * 复制数组最好用System.arraycopy 逐个复制,最慢;批量复制,最快 
98.          * @author yifangyou 
99.      * @since 2011-08-16 09:35:00 
100.          */
101.           
102. //      copyArray(); 
103. /* 
104.          * 复制ArrayList数组最好用addAll addAll,最快;clone,次之,逐个最慢 
105.          * @author yifangyou 
106.      * @since 2011-08-16 09:35:00 
107.          */
108. //      copyArrayList(); 
109. /* 
110.          * 复制Map最好用逐个复制最快,putAll最简单 
111.          * @author yifangyou 
112.      * @since 2011-08-16 09:35:00 
113.          */
114.         copyMap();  
115.  
116.       
117.     }  
118.  
119. int localN = 0;  
120. static int staticN = 0;  
121.  
122. /* 
123.      * 避免在循环条件中使用复杂表达式 
124.      * @author yifangyou 
125.      * @since 2011-08-16 09:35:00 
126.      */
127. public static void
128. new
129.  
130. for (int i = 0; i < 10000000; i++) {  
131.             a.add(i);  
132.         }  
133.  
134. long
135. // 循环条件中使用复杂表达式 
136. new
137. for (int i = 0; i < a.size(); i++) {  
138. int
139.         }  
140. new
141.  
142. // 循环条件中不使用复杂表达式 
143. new
144. for (int i = 0, maxlen = a.size(); i < maxlen; i++) {  
145. int
146.         }  
147. new
148.     }  
149.  
150. /* 
151.      * 如果只是查找单个字符的话,用charAt()代替startsWith() 
152.      * @author yifangyou 
153.      * @since 2011-08-16 09:35:00 
154.      */
155. public static void
156. "sdfsdfsdfsdfdssssssssssssssssssssssssssssdfffffffffffffffa";  
157. long
158. // startsWith 
159. new
160. for (int i = 0; i < 10000000; i++) {  
161. if (s.startsWith("a")) {  
162.  
163.             }  
164.         }  
165. new
166. // charAt 
167. new
168. for (int i = 0; i < 10000000; i++) {  
169. if (s.charAt(0) == 'a') {  
170.  
171.             }  
172.         }  
173. new
174.           
175. // charAt 
176. new
177. for (int i = 0; i < 10000000; i++) {  
178. if ("ab".equals("abcdssdds".substring(0, 2))) {  
179.  
180.             }  
181.         }  
182. new
183.  
184.     }  
185.  
186. /* 
187.      * 能够使用移位的乘除,最好用移位 
188.      * @author yifangyou 
189.      * @since 2011-08-16 09:35:00 
190.      */
191. public static void
192. long
193. int
194. // 
195. new
196.  
197. for (int i = 0; i < 10000000; i++) {  
198. 333333333 / 8;  
199.         }  
200. new
201. // charAt 
202. new
203. for (int i = 0; i < 10000000; i++) {  
204. 333333333 >> 3;  
205.         }  
206. new
207.     }  
208.  
209. /* 
210.      * 只有一个字符的字符串拼接,用''代替"" 
211.      * @author yifangyou 
212.      * @since 2011-08-16 09:35:00 
213.      */
214. public static void
215. long
216.  
217. new
218. "123";  
219. for (int i = 0; i < 10000000; i++) {  
220. "d";  
221.         }  
222. new
223. // charAt 
224. new
225. for (int i = 0; i < 10000000; i++) {  
226. 'd';  
227.         }  
228. new
229.     }  
230.  
231. /** 
232.      * try catch最好不要放在循环里 
233.      * @author yifangyou 
234.      * @since 2011-08-16 09:35:00 
235.      */
236. public static void
237. long
238. new
239. for (int i = 0; i < 10000000; i++) {  
240. try
241. int a = Integer.parseInt("1");  
242. catch
243.  
244.             }  
245.         }  
246. new
247.  
248. new
249. try
250. for (int i = 0; i < 10000000; i++) {  
251. int a = Integer.parseInt("1");  
252.             }  
253. catch
254.  
255.         }  
256.  
257. new
258.  
259.     }  
260.  
261. /** 
262.      * switch的实现 map比较稳定,if最慢,switch在数量少于10个时最快,随着数量增加下降厉害,在switch最好把出现次数最多的判断放在最前面 
263.      * @author yifangyou 
264.      * @since 2011-08-16 09:35:00 
265.      */
266. public static void
267. new
268.             {  
269. int i = 0;  
270. this.put("a", i++);  
271. this.put("b", i++);  
272. this.put("c", i++);  
273. this.put("d", i++);  
274. this.put("e", i++);  
275.             }  
276.         };  
277. "e";  
278. int b = 0;  
279. long
280. new
281. for (int i = 0; i < 10000000; i++) {  
282. if ("a".equals(a)) {  
283. 0;  
284. else if ("b".equals(a)) {  
285. 1;  
286. else if ("c".equals(a)) {  
287. 2;  
288. else if ("d".equals(a)) {  
289. 3;  
290. else if ("e".equals(a)) {  
291. 4;  
292.             }  
293.         }  
294. new
295.  
296. new
297. for (int i = 0; i < 10000000; i++) {  
298.             b = types.get(a);  
299.         }  
300. new
301. int c = 14;//改为0的话则最快 
302. new
303. for (int i = 0; i < 10000000; i++) {  
304. switch
305. case 0:  
306. break;  
307. case 1:  
308. break;  
309. case 2:  
310. break;  
311. case 3:  
312. break;  
313. case 4:  
314. break;  
315. case 5:  
316. break;  
317. case 6:  
318. break;  
319. case 7:  
320. break;  
321. case 8:  
322. break;  
323. case 9:  
324. break;  
325. case 10:  
326. break;  
327. case 11:  
328. break;  
329. case 12:  
330. break;  
331. case 13:  
332. break;  
333. case 14:  
334. break;  
335. default:  
336. break;  
337.             }  
338.         }  
339.  
340. new
341.     }  
342.  
343. /* 
344.      * 对于常量字符串,用'String' 代替 'StringBuffer' ,节省空间,节省一半时间 
345.      * @author yifangyou 
346.      * @since 2011-08-16 09:35:00 
347.      */
348. public static void
349. new StringBuffer("Hello");  
350. int maxlen=1000000;  
351. long
352. new
353. for (int i = 0; i < maxlen; i++) {  
354. new String("Hello ") + "World!";  
355.         }  
356. new
357.           
358. new
359. for (int i = 0; i < maxlen; i++) {  
360. new StringBuffer("Hello ").append("World!");  
361.         }  
362. new
363.     }  
364.  
365. /* 
366.      * 用'StringTokenizer' 代替 'indexOf()' 和'substring()' 
367.      * 字符串的分析在很多应用中都是常见的。使用indexOf 
368.      * ()和substring()来分析字符串容易导致StringIndexOutOfBoundsException。 
369.      * 而使用StringTokenizer类来分析字符串则会容易一些,效率也会低一些。 
370.      * @author yifangyou 
371.      * @since 2011-08-16 09:35:00 
372.      */
373. public static void
374. "www.a.com.";  
375. long
376. new
377.  
378. for (int i = 0; i < 100000; i++) {  
379. int index = 0;  
380. while ((index = domain.indexOf(".", index + 1)) != -1) {  
381. 1, domain.length());  
382. // System.out.println(domain.substring(index+1, 
383. // domain.length())); 
384.             }  
385.         }  
386. new
387. new
388. for (int i = 0; i < 100000; i++) {  
389. new StringTokenizer(domain, ".");  
390. while
391.                 st.nextToken();  
392. // System.out.println(st.nextToken()); 
393.             }  
394.         }  
395. new
396.     }  
397.  
398. /* 
399.      * 不要在循环体中实例化变量 在循环体中实例化临时变量将会增加内存消耗 
400.      * @author yifangyou 
401.      * @since 2011-08-16 09:35:00 
402.      */
403. public static void
404. new
405. int maxlen = 10000000;  
406. for (int i = 0; i < maxlen; i++) {  
407.             a.add(i);  
408.         }  
409. long
410. new
411. for (int i = 0; i < maxlen; i++) {  
412. new
413.             o = a.get(i);  
414.         }  
415. new
416. new
417. new
418. for (int i = 0; i < maxlen; i++) {  
419.             o = a.get(i);  
420.         }  
421. new
422.     }  
423.  
424. /* 
425.      * 确定 StringBuffer的容量 
426.      * StringBuffer的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小,就会重新分配内存 
427.      * ,创建一个更大的数组,并将原先的数组复制过来,再丢弃旧的数组。在大多数情况下,你可以在创建 
428.      * StringBuffer的时候指定大小,这样就避免了在容量不够的时候自动增长,以提高性能。 
429.      * @author yifangyou 
430.      * @since 2011-08-16 09:35:00 
431.      */
432. public static void
433. int maxlen = 1000000;  
434. long
435. new
436. for (int i = 0; i < maxlen; i++) {  
437. new StringBuffer(); // violation 
438. "hellosdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");  
439.         }  
440. new
441. new
442. for (int i = 0; i < maxlen; i++) {  
443. new StringBuffer(128); // violation 
444. "hellosdffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");  
445.         }  
446. new
447.     }  
448.  
449. /* 
450.      * 尽可能的使用栈变量 如果一个变量需要经常访问,那么你就需要考虑这个变量的作用域了。static? 
451.      * local?还是实例变量?访问静态变量和实例变量将会比访问局部变量多耗费2-3个时钟周期。 
452.      * @author yifangyou 
453.      * @since 2011-08-16 09:35:00 
454.      */
455. public static void
456. int maxlen = 100000000;  
457. long
458. int n = 0;  
459. new
460. // 局部变量 
461. new
462. for (int i = 0; i < maxlen; i++) {  
463.             n = i;  
464.         }  
465. new
466. // 类变量 
467. new
468. for (int i = 0; i < maxlen; i++) {  
469.             test.localN = i;  
470.         }  
471. new
472.  
473. // 静态变量 
474. new
475. for (int i = 0; i < maxlen; i++) {  
476.             Test.staticN = i;  
477.         }  
478. new
479.     }  
480. //   
481. //  /*1.尽量使用final修饰符。 
482. //带有final修饰符的类是不可派生的。在JAVA核心API中,有许多应用final的例子,例如java.lang.String。为String类指定final防止了使用者覆盖length()方法。另外,如果一个类是final的,则该类所有方法都是final的。java编译器会寻找机会内联(inline)所有的final方法(这和具体的编译器实现有关)。此举能够使性能平均提高50%。 
483. //   */ 
484. //  public static void test11() { 
485. //      int maxlen = 10000000; 
486. //      long startTime; 
487. //      int n = 0; 
488. //       
489. //      // 普通类 
490. //      startTime = new Date().getTime(); 
491. //      A a = new A(); 
492. //      for (int i = 0; i < maxlen; i++) { 
493. //          a.inc(); 
494. //      } 
495. //      System.out.println(new Date().getTime() - startTime); 
496. //       
497. //      // final类 
498. //      startTime = new Date().getTime(); 
499. //      FinalA finalA = new FinalA(); 
500. //      for (int i = 0; i < maxlen; i++) { 
501. //          finalA.inc(); 
502. //      } 
503. //      System.out.println(new Date().getTime() - startTime); 
504. //  } 
505.  
506. /** 
507.      * 复制数组最好用System.arraycopy 逐个复制,最慢;批量复制,最快 
508.      * @author yifangyou 
509.      * @since 2011-08-16 09:35:00 
510.      */
511. static void
512. int[] array1 = new int[10000000];  
513. int[] array2 = new int[10000000];  
514. for (int i = 0, maxlen = array1.length; i < maxlen; i++) {  
515.             array1[i] = i;  
516.         }  
517.  
518. long
519. // 逐个复制,最慢 
520. new
521.  
522. for (int i = 0, maxlen = array2.length; i < maxlen; i++) {  
523. // Violation 
524.         }  
525. new
526.  
527. // 批量复制,最快 
528. new
529. 0, array2, 0, 10000);  
530. new
531.  
532.     }  
533.  
534. /* 
535.      * 复制ArrayList数组最好用addAll addAll,最快;clone,次之,逐个最慢 
536.      * @author yifangyou 
537.      * @since 2011-08-16 09:35:00 
538.      */
539. static void
540. int maxlen = 1000000;  
541. new
542. new
543. new
544.         ArrayList<Integer> array4;  
545. for (int i = 0; i < maxlen; i++) {  
546.             array1.add(i);  
547.         }  
548.  
549. long
550. // 逐个复制,最慢 
551. new
552.  
553. for (int i = 0; i < maxlen; i++) {  
554. // Violation 
555.         }  
556. new
557.  
558. // 批量复制,最快 
559. new
560.         array3.addAll(array1);  
561. new
562.  
563. // 克隆,次快 
564. new
565.         array4 = (ArrayList<Integer>) array1.clone();  
566. new
567. 0, 4);  
568. "array1[0]=" + array1.get(0));  
569. "array4[0]=" + array4.get(0));  
570.  
571.     }  
572.  
573. /* 
574.      * 复制Map最好用逐个复制最快,putAll最简单 
575.      * @author yifangyou 
576.      * @since 2011-08-16 09:35:00 
577.      */
578. static void
579. int maxlen = 1000000;  
580. new
581. new
582. new
583. new
584. for (int i = 0; i < maxlen; i++) {  
585.             map1.put(i, i);  
586.         }  
587.  
588. long
589. // 逐个复制,最快 
590. new
591.         Set<Integer> key = map1.keySet();  
592. for
593.             Integer k = (Integer) it.next();  
594.             map2.put(k, map1.get(k));  
595.         }  
596. new
597.  
598. // 批量复制,最慢 
599. new
600.         map3.putAll(map1);  
601. new
602. "map2[9999]=" + map2.get(9999));  
603. "map3[9999]=" + map3.get(9999));  
604.  
605. // 逐个复制,次快 
606. new
607.         Set<Map.Entry<Integer, Integer>> set = map1.entrySet();  
608. for
609.                 .hasNext();) {  
610.             Map.Entry<Integer, Integer> entry = (Map.Entry<Integer, Integer>) it  
611.                     .next();  
612.             map4.put(entry.getKey(), entry.getValue());  
613.         }  
614. new
615.  
616.     }  
617.  
618. }


转载于:https://blog.51cto.com/yifangyou/641251