String与StringBuffer效率的比较
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效率的比较的更多相关文章
- java中String StringBuilder StringBuffer比较和效率(性能)测试
string stringbuilder stringbuffer三者的区别 从JDK源码看,String.StringBuilder.StringBuffer都是存放在char[] 数组字符串. 简 ...
- String、StringBuffer与StringBuilder之间区别
关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺点,到底什么时候该用谁呢?下面我们从以下几点说明一下 1.三者在执行速度方面的比较:StringBuilder > String ...
- (转)String、StringBuffer与StringBuilder之间区别
原文地址: http://www.cnblogs.com/A_ming/archive/2010/04/13/1711395.html 关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺 ...
- String、Stringbuffer、StringBuilder的区别(转载)
最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,StringBuilder的东西,现在整理一下. 关于这三个类在字符串处理中的位置不言而喻,那 ...
- String、StringBuffer和StringBuilder的深入解析
今天闲来无事,整理了下平时记录在印象笔记里的java开发知识点,整理到String,StringBuffer以及StringBuilder的区别时突然又产生了新的疑惑,这些区别是怎么产生的?温故为何能 ...
- String、StringBuffer、StringBuilder的区别
在日常开发过程中String字符串估计是被用到最多的变量了,最近看了一些String.StringBuffer和StringBuilder的东西,三者都可以对字符串进行操作,他们究竟有什么区别,以及适 ...
- String、StringBuffer、StringBuilder的一些小经验……
一说String.StringBuffer和StringBuilder,想必大家都很熟悉,这三者经常在我们的面试题中出现,我也是看到了关于这三个的经典面试题,才触动了我之前工作中的一些经历,故而根据我 ...
- java中String、StringBuffer、StringBuilder的区别
java中String.StringBuffer.StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题.现在总结一下,看看他们的不同与相同. 1.可变与不可 ...
- String、StringBuffer与StringBuilder之间区别[全屏看文]
String.StringBuffer与StringBuilder之间区别[全屏看文] 最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,S ...
随机推荐
- vue的slot的使用问题
slot的使用问题 根据官方文档来说,有三种使用方式 https://cn.vuejs.org/v2/guide/components.html#%E4%BD%BF%E7%94%A8%E6%8F%92 ...
- A网页高度随B内容而自然变化兼容各种浏览器
今天是星期一,昨天又没有睡好,眼睛干干的,还有点痛疼,于是不想干啥.但是心里又不觉得过意不去,浪费时间呀,考虑再三把自己前面实现的一个东西发了上来.算是今天的功劳,没有过多的文字描述,纯粹是贴图片和代 ...
- C++进阶2. typedef用法
C++ 中的typedef用法 20131011 Typedef在C++中是一个关键字,他的用法有多重,但是自己又说不全面,所以整理一下: 1.用类型的别名 typedef char* PChar; ...
- matlab eye 函数
eye(n,n) 产生一个n*n的单位矩阵 eye(n,m) 产生一个n*m的单位矩阵 eye(3,3) ans = 1 0 0 0 1 0 0 0 1 eye(3,4) ans = 1 0 0 0 ...
- rsync的服务端和客户端搭建
首先要看看有没有rsync,没有就按装一个rsync 1配置文件 然后创建rsyncd.conf文件,并添加如下内容(文件默认不存在) [root@chensiqi2 backup]# cat /et ...
- RxJava 详解
给 Android 开发者的 RxJava 详解: http://gank.io/post/560e15be2dca930e00da1083#toc_1
- ZOJ-2972-Hurdles of 110m(线性dp)
Hurdles of 110m Time Limit: 2 Seconds Memory Limit: 65536 KB In the year 2008, the 29th Olympic ...
- C++中几个值得分析的小问题(2)
下面有3个小问题,作为C++ Beginner你一定要知道错在哪里了. 1.派生类到基类的引用或指针转换一定“完美”存在? 一般情况,你很可能会认为:派生类对象的引用或指针转换为基类对象的引用或指针是 ...
- Xcode 8 插件安装
1.删除旧插件 cd ~/Library/Application\ Support/Developer/Shared/Xcode/Plug-in rm -rf ../Plug-ins 2.Xcode重 ...
- TeamView
1.TeamView TeamViewer是一个能在任何防火墙和NAT代理的后台用于远程控制,桌面共享和文件传输的简单且快速的解决方案.为了连接到另一台计算机,只需要在两台计算机上同时运行 TeamV ...