String str = “”;

for (int i=0; i<100; i++)

str += “a”;

可是你知道在内存中会产生多少的垃圾出来吗?总共会有a、aa、aaa、

aaa….,无疑的,上述的程序虽然简单,但浪费了不少的内存,而且产

生对象和对象的存取也会花掉不少的时间,我们加上几行程序代码来测试

花的时间和内存:

long startTime = System.currentTimeMillis();

long startMem = Runtime.getRuntime().freeMemory();

for (int i=0; i<1000; i++)

str += "a";

long endMem = Runtime.getRuntime().freeMemory();

System.out.println("Use memory: "+ (startMem - endMem));

long endTime = System.currentTimeMillis();

System.out.println("Use Time: "+ (endTime – startTime));

Use memory: 138688

Use Time: 16

上面的程序在笔者的PIII-800的计算机上跑,平均花了50 ms和151256 bytes

的内存,时间还好,但内存使用量算蛮大的了。那我们要如何来改进

让程序更有效率呢?因为String对象是不可修改的,可是程序中又常需要

这样的一个动作,所以Java提供了另外一个类别,专门来处理字符串运算用

的,这个类别就叫作StringBuffer。StringBuffer类别提供了很多方法来

做字符串的运算,但如附加、删除、插入、反转、替换等等…。我们就用

StringBuffer类别所提供的附加(append)方法来做到跟上面那个例子同样

的结果:

StringBuffer sb = new StringBuffer();

long startTime = System.currentTimeMillis();

long startMem = Runtime.getRuntime().freeMemory();

for (int i=0; i<1000; i++)

sb.append(“a”);

long endMem = Runtime.getRuntime().freeMemory();

System.out.println("Use memory: "+ (startMem - endMem));

long endTime = System.currentTimeMillis();

Use memory: 4976

Use Time: 0

修改过的程序在笔者计算机上跑,平均花了0 ms和4854 bytes的内存。

0 ms?!多跑几次有时会到10 ms,要看你计算机CPU目前的负载如何,不

过跟前面的例子比较起来,已经算是快了,而且内存也使用的非常少

。这只是个小小的例子,如果字符串量再大一点,两者的差异会更明显。

所以结论就是,如果你的程序中会对字符串做大量的修改时,请改用

StringBuffer类别,它会明显示改进你程序的效率。至于StringBuffer

类别所提供的方法详细的使用说明,就请自行参阅Java API。

****************************************************************************

[转自]http://www.newsmth.NET/pc/pccon.PHP?id=1427&nid=55836&s=all

好几天没有来发日志了,主要是因为这两天都在陪mm,嘿嘿所以今天小小偷懒一下,把我下午总结的一个组内报告发上来吧,hoho下面就开始吧!(别扔蔬菜和鸡蛋,我错了还不行么……)

在java中java.lang.String类是最常用但也是最容易被滥用的一个类,它也是导致代码性能低下的一个主要原因。所以今天就来说说和String使用相关的一些不得不注意的地方:

例1 String的相加操作

一个效率低下的例子如下:

代码段1

String s1 = "Testing String";

String s2 = "Concatenation Performance";

String s3 = s1 + " " + s2;

因为java中的String类不可变的(immutable),所以必须使用StringBuffer作为中间临时存储。这一段代码的性能损耗在最后相加的时候,程序内部生成和销毁了一次StringBuffer对象,以及一个String对象,见下面的代码被编译之后的版本:

代码段2

StringBuffer s = new StringBuffer();

s.append("Testing String");

s.append(" ");

s.append("Concatenation Performance");

String s3 = s.toString();

而StringBuffer类的默认构造函数为:public StringBuffer() { this(16); }

也就是说StringBuffer创建的时候默认的长度是16,以后当进行append的时候,如果空间不够,则会调用私有函数将空间加倍并将内容拷贝到新的空间中,代码如下:

代码段3

public synchronized StringBuffer append(String str) {

if (str == null) {

str = String.valueOf(str);

}

int len = str.length();

int newcount = count + len;

if (newcount > value.length) expandCapacity(newcount);

str.getChars(0, len, value, count);

count = newcount; return this;

}

在代码段2(以及在代码段1的编译结果中),由于字符串追加操作的最后结果是“Testing String Concatenation Performance”,它有40个字符,StringBuffer的存储能力必须扩展两次,从而导致了两次代价昂贵的复制操作,这个是速度降低的致命原因。所以至少我们可以进行的一个优化是分配一个初始大小大于等于40的StringBuffer对象进行追加:

代码段4

StringBuffer s = new StringBuffer(45);

s.append("Testing String");

s.append(" ");

s.append("Concatenation Performance");

String s3 = s.toString();

例2 避免多次的String相加:
看下面的例子:

代码段5

String s = "";

int sum = 0;

for(int I=1; I<10; I++) {

sum += I;

s = s + "+" +I

}

s = s + "=" + sum;

这段代码中循环中每次都进行了一次StringBuffer对象和String对象的创建和销毁,这样的开销很大而且不必要,如果使用下面的代码进行改进,就可以避免这样的情况:

代码段6

StringBuffer sb = new StringBuffer();

int sum = 0;

for(int I=1;

I<10; I++){

sum + = I;

sb.append(I).append("+");

}

String s = sb.append("=").append(sum).toString();

例3

小结

得到的结论是:如果对字符串中的内容经常进行操作,特别是内容要修改时,那么使用StringBuffer,如果最后需要String,那么使用StringBuffer的toString()方法进行转换

String与StringBuffer效率的比较的更多相关文章

  1. java中String StringBuilder StringBuffer比较和效率(性能)测试

    string stringbuilder stringbuffer三者的区别 从JDK源码看,String.StringBuilder.StringBuffer都是存放在char[] 数组字符串. 简 ...

  2. String、StringBuffer与StringBuilder之间区别

    关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺点,到底什么时候该用谁呢?下面我们从以下几点说明一下 1.三者在执行速度方面的比较:StringBuilder >  String ...

  3. (转)String、StringBuffer与StringBuilder之间区别

    原文地址: http://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html 关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺 ...

  4. String、Stringbuffer、StringBuilder的区别(转载)

    最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,StringBuilder的东西,现在整理一下. 关于这三个类在字符串处理中的位置不言而喻,那 ...

  5. String、StringBuffer和StringBuilder的深入解析

    今天闲来无事,整理了下平时记录在印象笔记里的java开发知识点,整理到String,StringBuffer以及StringBuilder的区别时突然又产生了新的疑惑,这些区别是怎么产生的?温故为何能 ...

  6. String、StringBuffer、StringBuilder的区别

    在日常开发过程中String字符串估计是被用到最多的变量了,最近看了一些String.StringBuffer和StringBuilder的东西,三者都可以对字符串进行操作,他们究竟有什么区别,以及适 ...

  7. String、StringBuffer、StringBuilder的一些小经验……

    一说String.StringBuffer和StringBuilder,想必大家都很熟悉,这三者经常在我们的面试题中出现,我也是看到了关于这三个的经典面试题,才触动了我之前工作中的一些经历,故而根据我 ...

  8. java中String、StringBuffer、StringBuilder的区别

    java中String.StringBuffer.StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题.现在总结一下,看看他们的不同与相同. 1.可变与不可 ...

  9. String、StringBuffer与StringBuilder之间区别[全屏看文]

    String.StringBuffer与StringBuilder之间区别[全屏看文]   最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,S ...

随机推荐

  1. Java基础学习-接口-概述以及成员特点

    package interfaceclass; /*接口的概述: * 接口解决的问题: * 因为java中的继承的单一局限性(子类只能继承一个父类),为了打破这个局限,java语言提供了一个机制,接口 ...

  2. vue-keep-alive

    查看github源代码    https://github.com/Diamondjcx/vue-test Vue keep-alive实践总结   <keep-alive>是Vue的内置 ...

  3. 学习三部曲:WHAT、HOW、WHY

    一个人学习的过程要经历以下三步,才可以说得上"学会"两字: 第一步:WHAT 所谓的"WHAT",就是搞清楚某个东东是什么?有什么用?有什么语法?有什么功能特性 ...

  4. EasyDSS RTMP流媒体服务器中调用videojs播放rtmp视频显示在左上角问题

    本文转自EasyDarwin团队成员Penggy的博客:http://www.jianshu.com/p/f63f5b7c691b 问题描述: 近期我开发了一款新一代的RTMP/HLS流媒体服务器软件 ...

  5. 利用pandas随机切分csv文件

    把数据集随机切分为训练集和测试集 method 1: df = pd.read_csv('data/tgnb_merge.csv', encoding='utf-8') df.drop_duplica ...

  6. hdu 1098

    http://acm.hdu.edu.cn/showproblem.php?pid=1098 假设x=m时,65|f(m),即65|5*m^13+13*m^5+k*a*m 计算f(m+1)=(5*m^ ...

  7. 将自己的框架更新到cocopods上

    为了更方便的集成第三方框架有了cocopods 的, 当我们有了相对比较好的框架的时候如何更新到cocopods 供他人参考呢? 下面我一步一步带大家开源自己的框架. 第一步 把自己的框架更新到git ...

  8. Android Studio 默认 debug.keystore , apk打包,keystore.jks文件生成,根据keystore密钥获取SHA1安全码

    参考资料: https://blog.csdn.net/nimasike/article/details/51457229 https://www.cnblogs.com/zhangqie/p/643 ...

  9. OK335x mksd.sh hacking

    #! /bin/sh # mk3PartSDCard. # Licensed under terms of GPLv2 # 参考文档: # . sfidsk创建可启动分区问题 # http://seg ...

  10. WPF 自定义键盘焦点样式(FocusVisualStyle)

    WPF 自带的键盘焦点样式是与传统控件样式搭配的,但 WPF 凭着其强大的自定义样式的能力,做出与传统控件样式完全不同风格的 UI 简直易如反掌.这时,其自带的键盘焦点样式(FocusVisualSt ...