坚持英文原版阅读.
避免创建不必要的对象!
一.字符串
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循环操作或者隐藏循环操作里创建对象