Comparative example Comparative String, String StringBuilder ligation efficiency and thread-safe and StringBuffer StringBuilder

First, the efficiency of the connection string

Why use String slow connection string?

Little knowledge

After java in the array is initialized, the memory space occupied by the array length of the array is immutable.

Create a string, to allocate memory space for the string object will be consumed a certain amount of time (CPU) and space (memory) as the cost of the most basic data types, a large number of frequently create a string, to a great extent influence the program performance.

Excessive useless intermediate object

Each time the connection string will create a new String object, with the increase in the number of stitching, this object will keep rising. For example, 100 times splicing need to create a String object 100 to be able to achieve their goals.

Why StringBuilder higher efficiency when connected?

Character array expansion mechanism:

void ensureCapacityInternal Private (int minimumCapacity) { 
         // if the minimum required capacity minimumCapacity array length is longer than the original 
        // overflow-Conscious code 
        IF (minimumCapacity - value.length> 0) { 
            value = Arrays.copyOf (value, 
                    newCapacity (minimumCapacity )); 
        } 
    } 
    
Private newCapacity int (int be minCapacity) { 
         // computing capacity after expansion newCapacity 
        // overflow-Conscious code 
        int newCapacity = (value.length <<. 1) + 2; 
        also less than the required after expansion // minimum capacity 
        IF (newCapacity - be minCapacity <0) { 
            // set new minimum required capacity is the capacity of the minimumCapacity 
            newCapacity be minCapacity =; 
        }
        // newCapacity has overflowed, if newCapacity bigger than the maximum capacity that can be allocated MAX_ARRAY_SIZE array. 
        return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity <0) 
            hugeCapacity (minCapacity)? 
            : newCapacity; 
    } 

    Private hugeCapacity int (int minCapacity) { 
        // the minimum required capacity of the memory overflow exception is thrown minCapacity greater than Integer.MAX_VALUE 
        IF ( Integer.MAX_VALUE - minCapacity <0) {// overflow 
            the throw an OutOfMemoryError new new (); 
        } 
        // if minCapacity between MAX_ARRAY_SIZE and Integer.MAX_VALUE, then the new capacity minCapacity, or used directly as a new MAX_ARRAY_SIZE capacity. 
        return (minCapacity> MAX_ARRAY_SIZE) 
            ? minCapacity: MAX_ARRAY_SIZE; 
    }

StringBuilder object when the original string is added: 

1. Append additional objects str 'null' is null character 

2. Verify whether the need for expansion of operations 

2.1 最小所需容量minimumCapacity是否比原数组长度要长,即当原数组长度不能满足所需最小容量时进行扩容操作。  
2.2 计算扩容之后的容量newCapacity,newCapacity = (value.length * 2) + 2。  
2.3 扩容后是否还小于所需的最小容量,如果小于则直接设置新容量为最小所需容量minimumCapacity。  
2.4 newCapacity是否溢出,newCapacity是否比数组所能分配的最大容量 MAX_ARRAY_SIZE 还要大。如果是的话则判断,最小所需容量minCapacity大于Integer.MAX_VALUE时抛出内存溢出异常,如果minCapacity介于MAX_ARRAY_SIZE和Integer.MAX_VALUE之间,则新的容量为minCapacity,否则直接使用MAX_ARRAY_SIZE作为新的容量。  

3.str.getChars () will be appended to the end value of str 

The reason for the high efficiency

  1. Expansion mechanism ensures that, only if they meet the conditions expansion  will generate a new array capacity expansion, the so most cases are in the original array operations, avoid excessive useless char [] objects, saving system resources overhead. minimumCapacity - value.length > 0

Code

/ ** 
 * Comparative concatenation speed 
 * 
 * @author: lingyejun 
 * @date: 2019/8/17 
 * @Describe: 
 * By @Modified: 
 * / 
public class LinkCompare { 

    / ** 
     * original concatenation 
     * 
     * @ Times param 
     * / 
    public static void linkByString (int Times) { 

        Long the startTime = System.currentTimeMillis (); 

        String initStr = ""; 
        for (int I = 0; I <Times; I ++) { 
            initStr initStr + = I; 
        } 

        Long = System.currentTimeMillis endTime (); 

        System.out.println ( "String connection" + times + "consumption times:" + (endTime - the startTime) + "MS"); 
    }

    /**
     * 使用StringBuilder连接字符串
     *
     * @param times
     */
    public static void linkByStringBuilder(int times) {

        Long startTime = System.currentTimeMillis();

        StringBuilder initStr = new StringBuilder();
        for (int i = 0; i < times; i++) {
            initStr.append(i);
        }

        Long endTime = System.currentTimeMillis();

        System.out.println("StringBuilder 连接 " + times + " 次 消耗:" + (endTime - startTime) + "ms");
    }


    /**
     * 使用StringBuffer连接字符串
     *
     * @param times
     */
    public static void linkByStringBuffer(int times) {

        Long startTime = System.currentTimeMillis();

        StringBuffer initStr = new StringBuffer();
        for (int i = 0; i < times; i++) {
            initStr.append(i);
        }

        Long endTime = System.currentTimeMillis();

        System.out.println("StringBuffer 连接 " + times + " 次 消耗:" + (endTime - startTime) + "ms");
    }


    public static void main(String[] args) {

        // 100000000
        linkByStringBuilder(40000);
        //-XX:+PrintGCDetails
        //linkByString(40000);

    }
}

Second, the security thread of relatively StringBuilder and String Buffer

Thread safety verification of StringBuffer

Reason not thread-safe

public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
    
public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }

Test code

import java.util.ArrayList;
import java.util.List;

/**
 * StringBuilder和StringBuffer的并发测验
 *
 * @Author: lingyejun
 * @Date: 2019/8/17
 * @Describe:
 * @Modified By:
 */
public class SecurityCompare {

    public void stringBuilderTest() {

        // 初始化StringBuilder
        StringBuilder stringBuilder = new StringBuilder();

        // joinList
        List<StringBuilderThread> joinList = new ArrayList<>();

        // 模拟并发场景
        for (int i = 0; i < 1000; i++) {
            StringBuilderThread sbt = new StringBuilderThread(stringBuilder);
            sbt.start();
            joinList.add (SBT); 
        }

        // wait append thread execution is completed before execution of the main thread 
        for (StringBuilderThread Thread: joinlist) { 
            the try { 
                Thread.join (); 
            } the catch (InterruptedException E) { 
                e.printStackTrace (); 
            } 
        } 

        // print the final results 
        System.out.println ( "StringBuilder append concurrent results:" + stringBuilder.length ()); 
    } 

    public void stringBufferTest () { 

        // initialize the stringBuffer 
        the stringBuffer stringBuffer the stringBuffer new new = (); 

        // joinlist 
        List <StringBufferThread> = new new joinlist the ArrayList <> (); 

        // simulate concurrent scenes
        for (int I = 0; I <1000; I ++) { 
            StringBufferThread SBF = new new StringBufferThread (stringBuffer); 
            sbf.start (); 
            joinList.add (SBF); 
        } 

        // append waiting thread execution is completed before execution of the main thread 
        for (StringBufferThread Thread: joinlist) { 
            the try { 
                Thread.join (); 
            } the catch (InterruptedException E) { 
                e.printStackTrace (); 
            } 
        } 

        // print the final result 
        System.out.println ( "StringBuffer append concurrent results:" stringBuffer.length + ()); 
    } 


    public static void main (String [] args) {
 
        SecurityCompare securityCompare new new SecurityCompare = ();

        securityCompare.stringBuilderTest();
        securityCompare.stringBufferTest();

    }

    public static class StringBuilderThread extends Thread {

        private StringBuilder stringBuilder;

        public StringBuilderThread(StringBuilder stringBuilder) {
            this.stringBuilder = stringBuilder;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            stringBuilder.append("a");
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    private static class StringBufferThread extends Thread {

        private StringBuffer stringBuffer;

        public StringBufferThread(StringBuffer stringBuffer) {
            this.stringBuffer = stringBuffer;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            stringBuffer.append("a");
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace (); 
            } 

        } 
    } 
}

CONCLUSIONS

1.String string of fixed length, StringBuilder StringBuffer and a variable-length string.
2.StringBuffer is thread-safe, StringBuilder is not thread safe.
The default initial capacity 3.StringBuilder and StringBuffer is 16, you can estimate in advance the length of the string of good, to further reduce the overhead caused by expansion.

 

Guess you like

Origin www.cnblogs.com/lingyejun/p/11407615.html