Java| StringBuilder与StringBuffer在单线程下的性能测试

本文将在单线程的场景下测试Stringbuilder 与StringBuffer 的相关性能.

下面的代码我将针对 StringBuffer 和 StringBuilder 对象在执行多次 append()andinsert() 后对比对程序性能的影响.

package com.yveshe;

import java.util.GregorianCalendar;

public class StringBuilderStringBufferPerformance {

    public static void main(String[] args) {
        System.gc();

        long startTime = new GregorianCalendar().getTimeInMillis();
        long startMemory = Runtime.getRuntime().freeMemory();
        StringBuffer sb = new StringBuffer();
        // StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 100000; i++) {
            sb.append(":" + i);
            sb.insert(i, "Yves");
        }
        long endTime = new GregorianCalendar().getTimeInMillis();
        long endMemory = Runtime.getRuntime().freeMemory();
        System.out.println("Time Taken:" + (endTime - startTime));
        System.out.println("Memory used:" + (startMemory - endMemory));
    }

}

我将上面代码中的 i 值从1,000改为10,0000,并记录了所花的时间和使用的内存。 我为 StringBuffer 对象运行了相同的代码,以检查时间和内存使用情况。

Java 1.8下结果如下

Time

Value of i 1,000 10,000 100,000
StringBuffer 6 133 22302
StringBuilder 5 149 23210

Memory

Value of i 1,000 10,000 100,000
StringBuffer 461368 2140424 18726880
StringBuilder 461368 2140400 18726856

从上面的结果看我并有看到StringBuffer 或 StringBuilder 对象在执行时间上有什么不同。
从逻辑上讲,StringBuilder 应该在单线程环境下执行得很好,但是10,000次迭代的情况却不是这样。究竟问题出现在哪里呢?

分析原因:
在我的程序中,大部分时间是通过insert操作进行的,因为它需要大量的内存分配和垃圾回收,因为内存中在不断使用Arrays.copyOf进行扩容,所以我决定从测试中删除insert操作。其次sb.append(":" + i);会产生大量的 StringBu *对象.这里解语法糖我我们可以发现 最终代码为sb.append((new StringBu *(":")).append(i).toString());

所以在接下来的测试里我将测试代码修改成如下

    public static void main(String[] args) {
        System.gc();

        long startTime = new GregorianCalendar().getTimeInMillis();
        long startMemory = Runtime.getRuntime().freeMemory();
        StringBuffer sb = new StringBuffer();
        // StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 100000; i++) {
            sb.append(":").append(i);
        }
        long endTime = new GregorianCalendar().getTimeInMillis();
        long endMemory = Runtime.getRuntime().freeMemory();
        System.out.println("Time Taken:" + (endTime - startTime));
        System.out.println("Memory used:" + (startMemory - endMemory));
    }

Java 1.8结果如下:

Time

Value of i 10,000 100,000 10,000,000
StringBuffer 5 39 1550
StringBuilder 4 26 1413

Memory

Value of i 10,000 100,000 10,000,000
StringBuffer 461368 2525800 74091240
StringBuilder 461368 2525800 74091240

现在很明显,即使在单线程环境下,StringBuilder 也比 StringBuffer 性能更好,而且这种性能差异可能是由同步引起的。

你可能感兴趣的:(【Java-SE】)