① String aa = "aa" + "bb" + "cc";
② StringBuffer aa = new StringBuffer("aa" + "bb" + "cc");
③ StringBuffer aa = new StringBuffer();
aa.append("aa");
aa.append("bb");
aa.append("cc");以上3个方案哪个效率高??为什么??
② StringBuffer aa = new StringBuffer("aa" + "bb" + "cc");
③ StringBuffer aa = new StringBuffer();
aa.append("aa");
aa.append("bb");
aa.append("cc");以上3个方案哪个效率高??为什么??
解决方案 »
- 怎样比较C:if重的两个数(在线等)
- toArray()功能的实现
- java 判断一个节点是否存在,存在则更新,不存在则创建 在线等
- hibernate 级联 添加 (persist)时抓不到异常 (框架struts, spring)
- 为什么Java mail发出的信收不到?
- 急!急!急,怎么样能最快速的判断大批量数据的剩余次数,具体请看需要,谢谢
- 调查一下。
- 谁有关于java的DOM的例子??
- 日期的问题,我要的是一个字串就象:“200204160819”,怎么做?
- 请问java编制的程序主要运行在服务器端还是客户端?听说它的速度比较慢,怎么可以运行在服务器端呢?谢谢!
- 为什么出现“array required , but int found”??
- JMenu菜单中的项目过多,在屏幕上显示不全如何处理?
因为编译器已经直接自动计算好了,已经不是在运行的时候才进行+了StringBuffer比String好,主要是在一个循环中才会明显,如果直接就是一行过没有在循环体内就没有什么问题
首先我们要明白String+String在内存中的动作
比如:
String a = "a";
String b = "b";
String c = a + b;
实际上a+b的时候并不会把a和b所占的内存回收掉,而是a,b,c都占用一定的内存
而StringBuffer则不同.
public class performance {
long startTime;
long startMem;
long endTime;
long endMem;
long time;
long mem;
public void count() {
time = endTime-startTime;
mem = startMem - endMem;
}
public String toString() {
return "测试内存使用和运行时间";
}
public void print() {
System.out.println("Use memory: "+ mem);
System.out.println("Use Time: "+ time);
} public void Start() {
startTime = System.currentTimeMillis();
startMem = Runtime.getRuntime().freeMemory();
}
public void End() {
endMem = Runtime.getRuntime().freeMemory();
endTime = System.currentTimeMillis();
}
}
你可以写一个main方法测测
String aa = "aa" + "bb" + "cc";
}
②
for(int i=0; i<500; i++){
StringBuffer aa = new StringBuffer("aa" + "bb" + "cc");
}
③
{ StringBuffer aa = new StringBuffer();
aa.append("aa");
aa.append("bb");
aa.append("cc");
}哪个快??
String 是不变类 即是 final类型。
所以
每次产生String 时 都会在内存内 产生一份拷贝。
比如
String a="aaa";
String b="bb";
String c=a+b;
那么内存中将有 三个对象 产生三个副本。
而StringBuffer 则不同
它将2个字符串连接
而不会进行新的内存分配
使String类可以共享内存:
如 String a = "abc"; String b = "abc",此时,a和b共享内存(指向同一个内存地址)
不信你可以用System.out.println(a==b)试一下~~所以,此时内存中只建了一个"abc"的字符串~
这是String类的优势~~具体哪个效率高还真难说,不同的情况会有不同的结果~~
小数据量的时候无所谓啦就
应用StringBuffer,关键在于根据处理数据大小,设定一个适当的初始容量.
如果程序频繁的执行字符串连接操作.或其他的字符串修改操作.则使用StringBuffer类来实现.可以提高效率.
public class Test {
long startTime;
long startMem;
long endTime;
long endMem;
long time;
long mem; public static void main(String[] args) {
Test a = new Test();
a.Start();
for (int i = 0; i < 500; i++) {
//StringBuffer aa = new StringBuffer("aaaaaaaaaaaaaaaaa" + "bbbbbbbbbbbbbbbbbbbbbb" + "ccccccccccccccccccccc");
// StringBuffer aa = new StringBuffer();
// aa.append("aaaaaaaaaaaaaaaaa");
// aa.append("bbbbbbbbbbbbbbbbbbbbbb");
// aa.append("ccccccccccccccccccccc"); String aa = "aaaaaaaaaaaaaaaaa" + "bbbbbbbbbbbbbbbbbbbbbb" + "ccccccccccccccccccccc";
}
a.End();
a.count();
a.toString();
a.print();
} public void count() {
time = endTime - startTime;
mem = startMem - endMem; } public String toString() {
return "测试内存使用和运行时间";
} public void print() {
System.out.println("Use memory: " + mem);
System.out.println("Use Time: " + time);
} public void Start() {
startTime = System.currentTimeMillis();
startMem = Runtime.getRuntime().freeMemory();
System.out.println("start memory: " + startMem);
System.out.println("start Time: " + startTime);
} public void End() {
endMem = Runtime.getRuntime().freeMemory();
endTime = System.currentTimeMillis();
System.out.println("end memory: " + endMem);
System.out.println("end Time: " + endTime);
}
大家谁不信可以试试
第一个建立了4个String对象,但是aa内存分配是一次完成的
第2个建立了3个String对象,一个StringBuffer,StringBuffer的建立是初始化的String+16,所以内存占用量比1大,建立一个StringBuffer要比String慢,所以速度也不行
第3个,建立了3个String对象,一个StringBuffer,StringBuffer的初始大小是16,如果第一个append的字符串>16要重新分配内存,一次,大小是第一个子符串的大小+16,已此类推,如果append的字符串比较大的话,第3个方案要分配3次内存,所以速度最慢
曾经用sax解析一份大的xml文件的时候,把值放在String,用+连接。
运行一段时间,程序总会等待好几分钟来回收垃圾,而且这个时候什么事情都干不了的。
等待几分钟意味着时间是正常的100倍量级,甚至千倍。
大家都知道StringBuffer在连接字符方面效率高,但还要看是什么情况下用。
StringBuffer sb = new StringBuffer();
for(int i = 0; i < 10000; i++)
sb.append("FFFFF");和
String a = "";
for(int i = 0; i < 10000; i++)
a += "FFFFF";
你这样就可以发现其中的巨大差异
for (int i = 0; i < 500; i++) {
String aa = "aaaaaaaaaaaaaaaaa" + "bbbbbbbbbbbbbbbbbbbbbb" + "ccccccccccccccccccccc";
}
这样做法,首先编译器自动帮助你优化成
for (int i = 0; i < 500; i++) {
String aa = "aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccc";
}所以在这个过程中,根本没有生成任何对象(那个是字符串常量,只会在类中存在一份,aa每次都指向这个常量罢了),所以没有任何拷贝动作
for (int i = 0; i < 500; i++) {
StringBuffer aa = new StringBuffer("aaaaaaaaaaaaaaaaa" + "bbbbbbbbbbbbbbbbbbbbbb" + "ccccccccccccccccccccc"); }优化成:
for (int i = 0; i < 500; i++) {
StringBuffer aa = new StringBuffer("aaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccc");
}
即,除了一个常量以外,还会在循环中生成一个StringBuffer对象,但是它是在构造函数中已经完成了,没有后续函数调用!最后一种 :
for (int i = 0; i < 500; i++) {
StringBuffer aa = new StringBuffer();
aa.append("aaaaaaaaaaaaaaaaa");
aa.append("bbbbbbbbbbbbbbbbbbbbbb");
aa.append("ccccccccccccccccccccc");
}编译器无法优化(它没有这么聪明),所以这种方法会有三个字符串常量,并每次循环有构造函数外还额外调用多三次方法从上述可以看到,这个根本是因为编译器的优化造成的
如果你将程序改成
String constA = "aaaaaaaaaaaaaaaaa";
String constB = "bbbbbbbbbbbbbbbbbbbbbb";
String constC = "ccccccccccccccccccccc";
再将后面相应的换成上面的constA, constB, constC,你就会发现这三者的速度是相当的
String constB = "bbbbbbbbbbbbbbbbbbbbbb";
String constC = "ccccccccccccccccccccc";
long t1 = System.currentTimeMillis();
for (int i = 0; i < 500000; i++) {
1. //String aa = constA + constB + constC;2. //StringBuffer aa = new StringBuffer(constA + constB + constC);3. StringBuffer aa = new StringBuffer();
aa.append(constA);
aa.append(constB);
aa.append(constC);4. StringBuffer aa = new StringBuffer(constA);
aa.append(constB);
aa.append(constC);}
long t2 = System.currentTimeMillis();
System.out.println("(T2-T1):" + (t2 - t1));
在我的机器上面
1. 用时 700ms
2. 用时 1100ms
3. 用时 620ms
4. 用时 550ms
没别的意思,只是感觉你分析的不错,我是新手,
String a="afdsafda";
String a=a+"fs";还有更有效率的方法做到这件事情么
String b = a + "fs";这样的代码,编译器无法优化
但是这样可以:
final String a = "afdsafda";
final String b = a + "fs";
看了你的讲解是明白了不少。
但是我还是不明白1和2比3多消耗的时间在那里呢??