当前位置:编程学习 > JAVA >>

毁三观,StringBuffer与StringBuilder到底哪个更快

都说StringBuilder是单线程的,要比StringBuffer快,但是下面的代码,在我的机器上跑,StringBuffer的性能愣是比StringBuilder强。。。求高人解答,看看是我的测试方法不对还是什么个情况?

	public static void main(String[] args) {
insertTest();
}

public static void insertTest() {
int t = 10;
int[] times = { 10 * t, 100 * t, 1000 * t, 10000 * t, 15000 * t };
StringBuilder sbBuilder = new StringBuilder();
StringBuffer sbBuffer = new StringBuffer();
long l;
int i;
for (int time : times) {
l = System.currentTimeMillis();
for (i = 0; i < time; i++) {
stringBuilderInsert(sbBuilder, "hello world");
}
System.out.println("builder run " + time + " times insert take " + (System.currentTimeMillis() - l) + "ms");
l = System.currentTimeMillis();
for (i = 0; i < time; i++) {
stringBufferInsert(sbBuffer, "hello world");
}
System.out.println("buffer run " + time + " times insert take " + (System.currentTimeMillis() - l) + "ms");
}
}

public static StringBuilder stringBuilderInsert(StringBuilder dest, String str) {
int offset = (int) (Math.random() * dest.length());
dest.insert(offset, str);
return dest;
}

public static StringBuffer stringBufferInsert(StringBuffer dest, String str) {
int offset = (int) (Math.random() * dest.length());
dest.insert(offset, str);
return dest;
}

下面是运行的结果
性能 stringbuffer stringbuilder 测试 --------------------编程问答-------------------- http://sxzgll.iteye.com/blog/159292

看这个吧,。。。什么叫“单线程的”,你确实需要毁三观再来。 --------------------编程问答-------------------- 单线程的?不是线程安全的区别么 --------------------编程问答-------------------- StringBuilder是非线程安全的,StringBuffer是线程安全的.

两个都是继承于java.lang.AbstractStringBuilder的,最终调用的都是这个AbstractStringBuilder类里面定义的方法.

StringBuilder只是少一些锁的开销而已,单个线程下能有什么区别...? --------------------编程问答-------------------- 在单线程下应该时间不会有太大差距才对。 --------------------编程问答-------------------- 循环一百万次,试试就知道了 --------------------编程问答-------------------- 原来如此。。 --------------------编程问答-------------------- 做测试有一个基本原则,就是可重复性。你用了random,就违背了这条原则,你没法重复你的实验,对于实验误差就不可能用统计学来修正,因为你每一次实验都不一样。

做Java测试有一个非常需要注意的点,就是有时候你并不知道你在测试什么。
1. 当你把两个函数放在一个地方测试的时候,前一个函数很有可能影响后一个函数的结果
2. 当你像我说的去掉了随机性,一不小心JVM就会当做你在做无用功,而把你要测试的代码直接跳过了,然后你就得到了一个很惊艳的值
3. 做测试之前一定要做预热(先让你要测试的代码跑个10000次),之后才能开始做测试
4. 做测试的时候尽量减少内存分配,如果不行,就尽可能减少内存释放,因为你无法控制GC的执行时间,而这对于微秒精度的性能测试是致命的
--------------------编程问答--------------------
引用 3 楼 etnet 的回复:
StringBuilder是非线程安全的,StringBuffer是线程安全的.

两个都是继承于java.lang.AbstractStringBuilder的,最终调用的都是这个AbstractStringBuilder类里面定义的方法.

StringBuilder只是少一些锁的开销而已,单个线程下能有什么区别...?

+1

两个类差不多,区别主要就是线程安全与否。单线程时比较两个类没有意义,但是多线程时,因为线程安全的需要进行同步,所以效率上可以会差点。 --------------------编程问答--------------------
引用 3 楼 etnet 的回复:
StringBuilder是非线程安全的,StringBuffer是线程安全的.

两个都是继承于java.lang.AbstractStringBuilder的,最终调用的都是这个AbstractStringBuilder类里面定义的方法.

StringBuilder只是少一些锁的开销而已,单个线程下能有什么区别...?

+1

--------------------编程问答-------------------- 好吧,我的测试方法是有问题的,因为两个测试方法是在同一个JVM里运行的,所以。。。
后来我在不同的JVM里运行这两个方法,两者的方法差不太多
我2了。。。 --------------------编程问答--------------------
引用 7 楼 lcf 的回复:
做测试有一个基本原则,就是可重复性。你用了random,就违背了这条原则,你没法重复你的实验,对于实验误差就不可能用统计学来修正,因为你每一次实验都不一样。

做Java测试有一个非常需要注意的点,就是有时候你并不知道你在测试什么。
1. 当你把两个函数放在一个地方测试的时候,前一个函数很有可能影响后一个函数的结果
2. 当你像我说的去掉了随机性,一不小心JVM就会当做你在做无用功,而把你要测试的代码直接跳过了,然后你就得到了一个很惊艳的值
3. 做测试之前一定要做预热(先让你要测试的代码跑个10000次),之后才能开始做测试
4. 做测试的时候尽量减少内存分配,如果不行,就尽可能减少内存释放,因为你无法控制GC的执行时间,而这对于微秒精度的性能测试是致命的

这位大大,如果我想测试随机插入的性能,那可不可以使用random? --------------------编程问答--------------------
引用 11 楼 HallWong 的回复:
Quote: 引用 7 楼 lcf 的回复:

做测试有一个基本原则,就是可重复性。你用了random,就违背了这条原则,你没法重复你的实验,对于实验误差就不可能用统计学来修正,因为你每一次实验都不一样。

做Java测试有一个非常需要注意的点,就是有时候你并不知道你在测试什么。
1. 当你把两个函数放在一个地方测试的时候,前一个函数很有可能影响后一个函数的结果
2. 当你像我说的去掉了随机性,一不小心JVM就会当做你在做无用功,而把你要测试的代码直接跳过了,然后你就得到了一个很惊艳的值
3. 做测试之前一定要做预热(先让你要测试的代码跑个10000次),之后才能开始做测试
4. 做测试的时候尽量减少内存分配,如果不行,就尽可能减少内存释放,因为你无法控制GC的执行时间,而这对于微秒精度的性能测试是致命的

这位大大,如果我想测试随机插入的性能,那可不可以使用random?

不能。
你要建立一个100,000长度(或者你希望的任何长度)的int[],预先用random算好它们的值,然后存进一个文件。然后把两个测试函数分别写在两个main里面,每次分别用两个main来测试速度,将结果写入另两个文件,然后你就可以用excel之类的工具作统计学比较了。发布实验结果的时候一定要连所有源文件,包括产生int[]的代码一起发布。这样才是比较像样的benchmark。专业的benchmark当然还要包含gc的数据,测试平台配置等一些杂项 --------------------编程问答-------------------- 楼上有几个同学完全没理解楼主的意思。
StringBuffer是线程安全的,所以多出一些同步判断,所以才会在单线程的情况下相对于StringBuilder要慢。在多线程的情况下就会出现错误,哪有速度可言。 --------------------编程问答-------------------- 不加锁当然快 --------------------编程问答--------------------
引用 12 楼 lcf 的回复:
Quote: 引用 11 楼 HallWong 的回复:

Quote: 引用 7 楼 lcf 的回复:

做测试有一个基本原则,就是可重复性。你用了random,就违背了这条原则,你没法重复你的实验,对于实验误差就不可能用统计学来修正,因为你每一次实验都不一样。

做Java测试有一个非常需要注意的点,就是有时候你并不知道你在测试什么。
1. 当你把两个函数放在一个地方测试的时候,前一个函数很有可能影响后一个函数的结果
2. 当你像我说的去掉了随机性,一不小心JVM就会当做你在做无用功,而把你要测试的代码直接跳过了,然后你就得到了一个很惊艳的值
3. 做测试之前一定要做预热(先让你要测试的代码跑个10000次),之后才能开始做测试
4. 做测试的时候尽量减少内存分配,如果不行,就尽可能减少内存释放,因为你无法控制GC的执行时间,而这对于微秒精度的性能测试是致命的

这位大大,如果我想测试随机插入的性能,那可不可以使用random?

不能。
你要建立一个100,000长度(或者你希望的任何长度)的int[],预先用random算好它们的值,然后存进一个文件。然后把两个测试函数分别写在两个main里面,每次分别用两个main来测试速度,将结果写入另两个文件,然后你就可以用excel之类的工具作统计学比较了。发布实验结果的时候一定要连所有源文件,包括产生int[]的代码一起发布。这样才是比较像样的benchmark。专业的benchmark当然还要包含gc的数据,测试平台配置等一些杂项
受教了,这么做是尽可能的减小random方法产生的性能影响。 --------------------编程问答--------------------
引用 15 楼 HallWong 的回复:
Quote: 引用 12 楼 lcf 的回复:

Quote: 引用 11 楼 HallWong 的回复:

Quote: 引用 7 楼 lcf 的回复:

做测试有一个基本原则,就是可重复性。你用了random,就违背了这条原则,你没法重复你的实验,对于实验误差就不可能用统计学来修正,因为你每一次实验都不一样。

做Java测试有一个非常需要注意的点,就是有时候你并不知道你在测试什么。
1. 当你把两个函数放在一个地方测试的时候,前一个函数很有可能影响后一个函数的结果
2. 当你像我说的去掉了随机性,一不小心JVM就会当做你在做无用功,而把你要测试的代码直接跳过了,然后你就得到了一个很惊艳的值
3. 做测试之前一定要做预热(先让你要测试的代码跑个10000次),之后才能开始做测试
4. 做测试的时候尽量减少内存分配,如果不行,就尽可能减少内存释放,因为你无法控制GC的执行时间,而这对于微秒精度的性能测试是致命的

这位大大,如果我想测试随机插入的性能,那可不可以使用random?

不能。
你要建立一个100,000长度(或者你希望的任何长度)的int[],预先用random算好它们的值,然后存进一个文件。然后把两个测试函数分别写在两个main里面,每次分别用两个main来测试速度,将结果写入另两个文件,然后你就可以用excel之类的工具作统计学比较了。发布实验结果的时候一定要连所有源文件,包括产生int[]的代码一起发布。这样才是比较像样的benchmark。专业的benchmark当然还要包含gc的数据,测试平台配置等一些杂项
受教了,这么做是尽可能的减小random方法产生的性能影响。

不对。这么做是让实验公平。不然前后两次实验的数据都不一样,怎么进行公平的比较? --------------------编程问答--------------------
引用 16 楼 lcf 的回复:
Quote: 引用 15 楼 HallWong 的回复:

Quote: 引用 12 楼 lcf 的回复:

Quote: 引用 11 楼 HallWong 的回复:

Quote: 引用 7 楼 lcf 的回复:

做测试有一个基本原则,就是可重复性。你用了random,就违背了这条原则,你没法重复你的实验,对于实验误差就不可能用统计学来修正,因为你每一次实验都不一样。

做Java测试有一个非常需要注意的点,就是有时候你并不知道你在测试什么。
1. 当你把两个函数放在一个地方测试的时候,前一个函数很有可能影响后一个函数的结果
2. 当你像我说的去掉了随机性,一不小心JVM就会当做你在做无用功,而把你要测试的代码直接跳过了,然后你就得到了一个很惊艳的值
3. 做测试之前一定要做预热(先让你要测试的代码跑个10000次),之后才能开始做测试
4. 做测试的时候尽量减少内存分配,如果不行,就尽可能减少内存释放,因为你无法控制GC的执行时间,而这对于微秒精度的性能测试是致命的

这位大大,如果我想测试随机插入的性能,那可不可以使用random?

不能。
你要建立一个100,000长度(或者你希望的任何长度)的int[],预先用random算好它们的值,然后存进一个文件。然后把两个测试函数分别写在两个main里面,每次分别用两个main来测试速度,将结果写入另两个文件,然后你就可以用excel之类的工具作统计学比较了。发布实验结果的时候一定要连所有源文件,包括产生int[]的代码一起发布。这样才是比较像样的benchmark。专业的benchmark当然还要包含gc的数据,测试平台配置等一些杂项
受教了,这么做是尽可能的减小random方法产生的性能影响。

不对。这么做是让实验公平。不然前后两次实验的数据都不一样,怎么进行公平的比较?

哦哦,理解有误 --------------------编程问答-------------------- 貌似楼主的电脑速度挺快

builder run 100 times insert take 0ms
buffer run 100 times insert take 1ms
builder run 1000 times insert take 2ms
buffer run 1000 times insert take 1ms
builder run 10000 times insert take 74ms
buffer run 10000 times insert take 85ms
builder run 100000 times insert take 7605ms
buffer run 100000 times insert take 7636ms
builder run 150000 times insert take 38561ms
buffer run 150000 times insert take 39384ms
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,