坚持英文原版阅读.
避免创建不必要的对象!
一.字符串
String s = new String("AA");//unnecessary String s = "AA";//instead第一行会在堆中分配内存空间
第二行会放在字符串常量池中
二.
对比以下代码:
static boolean isRomanNumeral(String s){ return s.matches("^(?=.)"); }private static final Pattern ROMAN = Pattern.compile("^(?=.)"); static boolean isRomanNumeral(String s){ return ROMAN.matcher(s).matches(); }
1.第一部分代码,在每次调用isRomanNumeral方法时都会生成一个"^(?=.)",调用完毕后被GC。查看s.matches("")方法源码:
package java.util.regex.Pattern.java
public static boolean matches(String regex, CharSequence input) { Pattern p = Pattern.compile(regex); Matcher m = p.matcher(input); return m.matches(); }进一步查看Pattern.compile(regex)方法:
public static Pattern compile(String regex) { return new Pattern(regex, 0); }每一次都会创建Pattern对象,代价很高
2.第二部分代码中的"^(?=.)",只生成一次,Pattern对象只创建一次。
三.
Long sum = 0L; for (int i = 0; i < Integer.MAX_VALUE; i++) { sum += i; } long sum = 0L; for (int i = 0; i < Integer.MAX_VALUE; i++) { sum += i; }
当sum为Long类型时,每次做sum += i操作,都会调用Long.valueOf(long l)方法,通过javap反编译可查看调用过程:
转存失败重新上传取消
JDK源码:
public static Long valueOf(long l) { final int offset = 128; if (l >= -128 && l <= 127) { // will cache return LongCache.cache[(int)l + offset]; } return new Long(l); }在此方法中,会创建一个Long包装类,效率较低。
测试效率:
public static void main(String[] args) { long before = new Date().getTime(); Long sum = 0L; for (int i = 0; i < Integer.MAX_VALUE; i++) { sum += i; } System.out.println("sum:" + sum); long end = new Date().getTime(); System.out.println("cost:" + (end - before)); }测试结果:
sum类Long包装类型:
sum:2305843005992468481
cost:3555
sum类long包装类型:
sum:2305843005992468481
cost:680
使用Long包装类型效率低5倍!
====》总结
1.尽量使用常量类
2.注意工具类的属性范围
3.尽量不在for循环操作或者隐藏循环操作里创建对象