关于String的性能优化

1.subString

String对象由偏移量,总长度,char数组组成。

在JDK6的subString的实现中,仅仅是改变的char数组的偏移量和总长度,新截取的字符串仍然包含了原有字符串的所有内容,并且占据了相应的内存空间,仅仅通过偏移量和长度来决定自己的取值,这就使得垃圾回收器不会把原有字符串占有的内存空间释放出来,如果进行大量的这样的操作会造成内存泄漏。

解决方法1:new String(str.subString(beginIndex,endIndex));
解决方法2:str.subString(beginIndex,endIndex)+”“;

反正目的都是让新生成的字符串不再占用原有字符串的引用,让垃圾回收器把原有字符串占用的内存空间释放出来。

然而这个情况JDK7中得到了改变,在进行字符串截取的时候创建了一个新的对象,不再和原有字符串是同一个引用。

2.字符串分割和查找

String对象提供了一个十分方便的split()方法供我们进行字符串的分割,但是这个方法的效率十分低下,我们在允许的情况下应该考虑使用StringTokenizer对象去进行字符串分割。

还有一种更加优化的字符串分割方法,那就是我们利用String对象的indexOf()和subString()自定义一个字符串分割方法。subString()方法采用的是用时间换空间的策略,它的效率是非常高的,同样indexOf()也是一个效率十分高的方法。

自定义分割方法

String str = "1;1;1;1;1;1;1;1;1;1;1;";
public String[] splitStr(String str,String regex){
    String splitStr = null;
    String[] strArray = new String[2];
    int index = str.indexOf(regex);//得到分割符的索引
    splitStr = str.subString(0,index)+"";//截取字符串
    str = str.subString(index+1);//处理剩下字符串
    strArray[0] = splitStr+"";
    strArray[1] = str+"";
    return strArray;
}

此方法可根据实际需要自行更改。

比较3种字符串分割方法

split()效率最低,StringTokenizer效率比split()高,自定义方法效率最高,但是可维护性和可读性差,只有当系统性能成为主要矛盾时考虑用这种方法,其他情况在条件允许的情况下优先考虑使用StringTokenizer对象。

字符串累加操作

方法1:
String str = "a"+"b"+"c";
这种方法看上去效率十分低,但是编译器会对这段代码进行优化,执行时间为0ms。
对于静态字符串的累加操作,JAVA在编译时会进行彻底的优化,将多个连接操作的字符串在编译时合成一个单独的长字符串。

方法2:

String str1 = "a";
String str2 = "b";
String str3 = "c";
String str = str1+str2+str3;

这段代码看上去效率十分低,但是在执行时却不然,因为编译器将这段代码优化成了

str = (new StringBuilder(String.valueOf(str1)).append(str2).append(str3).toString)

此时的执行效率与用StringBuilder差不多,但是我还是倾向于显示的调用StringBuffer/StringBuilder去进行字符串拼接,因为尽管编译器做出了极大的优化,但是在有些情况下编译器还是没有这么聪明,比如将上面的拼接字符串的代码放入循环中,程序就需要循环的创建StringBuilder对象,这无疑比只维护一个StringBuilder对象性能要低的多。

方法3:
利用StringBuffer/StringBuilder进行字符串拼接,效率很高。

StringBuffer和StringBuilder的选择
StringBuffer对每一个方法都做了同步,而StringBuilder没有。
StringBuffer:同步,线程安全,适用于多线程,效率较StringBuilder要低。
StringBuilder:不同步,线程不安全,不适用于多线程安全有要求的程序,效率较高。

此外,如果我们可以预估StringBuffer/StringBuilder的大小可以在初始化时就加入容量参数,如:
StringBuilder sb = new StringBuilder(58000);
因为这两个对象在进行扩容时涉及到了大量的内存复制操作,所以可以预估大小的化就可以减少这些操作从而提高性能。

参考书籍:
《JAVA程序性能优化》 葛一鸣

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值