都说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测试

解决方案 »

  1.   

    http://sxzgll.iteye.com/blog/159292看这个吧,什么叫“单线程的”,你确实需要毁三观再来。
      

  2.   

    StringBuilder是非线程安全的,StringBuffer是线程安全的.两个都是继承于java.lang.AbstractStringBuilder的,最终调用的都是这个AbstractStringBuilder类里面定义的方法.StringBuilder只是少一些锁的开销而已,单个线程下能有什么区别...?
      

  3.   

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

  4.   

    好吧,我的测试方法是有问题的,因为两个测试方法是在同一个JVM里运行的,所以
    后来我在不同的JVM里运行这两个方法,两者的方法差不太多
    我2了
      

  5.   

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

  6.   

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

  7.   

    楼上有几个同学完全没理解楼主的意思。
    StringBuffer是线程安全的,所以多出一些同步判断,所以才会在单线程的情况下相对于StringBuilder要慢。在多线程的情况下就会出现错误,哪有速度可言。
      

  8.   

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

  9.   

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

  10.   

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

  11.   

    貌似楼主的电脑速度挺快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