都说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;
}
下面是运行的结果
性能stringbufferstringbuilder测试
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;
}
下面是运行的结果
性能stringbufferstringbuilder测试
1. 当你把两个函数放在一个地方测试的时候,前一个函数很有可能影响后一个函数的结果
2. 当你像我说的去掉了随机性,一不小心JVM就会当做你在做无用功,而把你要测试的代码直接跳过了,然后你就得到了一个很惊艳的值
3. 做测试之前一定要做预热(先让你要测试的代码跑个10000次),之后才能开始做测试
4. 做测试的时候尽量减少内存分配,如果不行,就尽可能减少内存释放,因为你无法控制GC的执行时间,而这对于微秒精度的性能测试是致命的
后来我在不同的JVM里运行这两个方法,两者的方法差不太多
我2了
不能。
你要建立一个100,000长度(或者你希望的任何长度)的int[],预先用random算好它们的值,然后存进一个文件。然后把两个测试函数分别写在两个main里面,每次分别用两个main来测试速度,将结果写入另两个文件,然后你就可以用excel之类的工具作统计学比较了。发布实验结果的时候一定要连所有源文件,包括产生int[]的代码一起发布。这样才是比较像样的bench。专业的bench当然还要包含gc的数据,测试平台配置等一些杂项
StringBuffer是线程安全的,所以多出一些同步判断,所以才会在单线程的情况下相对于StringBuilder要慢。在多线程的情况下就会出现错误,哪有速度可言。
不能。
你要建立一个100,000长度(或者你希望的任何长度)的int[],预先用random算好它们的值,然后存进一个文件。然后把两个测试函数分别写在两个main里面,每次分别用两个main来测试速度,将结果写入另两个文件,然后你就可以用excel之类的工具作统计学比较了。发布实验结果的时候一定要连所有源文件,包括产生int[]的代码一起发布。这样才是比较像样的bench。专业的bench当然还要包含gc的数据,测试平台配置等一些杂项受教了,这么做是尽可能的减小random方法产生的性能影响。
不能。
你要建立一个100,000长度(或者你希望的任何长度)的int[],预先用random算好它们的值,然后存进一个文件。然后把两个测试函数分别写在两个main里面,每次分别用两个main来测试速度,将结果写入另两个文件,然后你就可以用excel之类的工具作统计学比较了。发布实验结果的时候一定要连所有源文件,包括产生int[]的代码一起发布。这样才是比较像样的bench。专业的bench当然还要包含gc的数据,测试平台配置等一些杂项受教了,这么做是尽可能的减小random方法产生的性能影响。
不对。这么做是让实验公平。不然前后两次实验的数据都不一样,怎么进行公平的比较?
不能。
你要建立一个100,000长度(或者你希望的任何长度)的int[],预先用random算好它们的值,然后存进一个文件。然后把两个测试函数分别写在两个main里面,每次分别用两个main来测试速度,将结果写入另两个文件,然后你就可以用excel之类的工具作统计学比较了。发布实验结果的时候一定要连所有源文件,包括产生int[]的代码一起发布。这样才是比较像样的bench。专业的bench当然还要包含gc的数据,测试平台配置等一些杂项受教了,这么做是尽可能的减小random方法产生的性能影响。
不对。这么做是让实验公平。不然前后两次实验的数据都不一样,怎么进行公平的比较?
哦哦,理解有误
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