Why does IDEA recommend removing StringBuilder and use "+" to concatenate strings?

Author: JD Retail Jiang Bo
Source: JD Cloud Developer Community

Everyone should have seen the following prompt when splicing strings:

Content translation: Report any usage of StringBuffer, StringBuilder or StringJoiner that can be replaced by a single java.lang.String concatenation. Using string concatenation can make your code shorter and simpler. This check will only report if the resulting concatenation is at least as efficient as the original code or more efficient.

It is generally accepted that StringBuilder is used for string splicing, so why does idea suggest that you use "+"? So what is the specific difference between StringBuilder and "+"? Let's explore it together.

Recommend an open source and free Spring Boot practical project:

https://github.com/javastacks/spring-boot-best-practice

1. Ordinary splicing

To splice several ordinary strings into one string, use "+" directly. Due to textbooks and other reasons, many people still think that using "+" consumes performance when splicing strings, and StringBuilder is the first choice.

In fact, starting from JDK5, the Java compiler has been optimized to use "+" to splice strings. After compilation, the compiler actually automatically optimizes to use StringBuilder.

Create a new test class StringTest, and create methods to use "+" to splice strings and use StringBuilder to splice strings; and add a new Junit test case to call splicing strings 100,000 times (here is not loop splicing, but multiple splicing, Because one splicing takes too little time to see the difference), printing takes time.

/**
 * 使用+拼接字符串
 */
public String concatenationStringByPlus(String prefix, int i) {
    return prefix + "-" + i;
}

/**
 * 使用StringBuilder拼接字符串
 */
public String concatenationStringByStringBuilder(String prefix, int i) {
    return new StringBuilder().append(prefix).append("-").append(i).toString();
}

/**
 * 测试使用+拼接字符串耗时
 */
@Test
public void testStringConcatenation01ByPlus() {
    long startTime = System.currentTimeMillis();
    int count = 100000;
    for (int i = 0; i < count; i++) {
        String str = concatenationStringByPlus("testStringConcatenation01ByStringBuilder:", i);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("testStringConcatenation01ByPlus,拼接字符串" + count + "次,花费" + (endTime - startTime) + "秒");
}

/**
 * 测试使用StringBuilder拼接字符串耗时
 */
@Test
public void testStringConcatenation02ByStringBuilder() {
    long startTime = System.currentTimeMillis();
    int count = 100000;
    for (int i = 0; i < count; i++) {
        String str = concatenationStringByStringBuilder("testStringConcatenation02ByStringBuilder:", i);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("testStringConcatenation02ByStringBuilder,拼接字符串" + count + "次,花费" + (endTime - startTime) + "秒");
}

Execute the Junit use case and see the time-consuming statistics output:

testStringConcatenation01ByPlus,拼接字符串100000次,花费33秒
testStringConcatenation02ByStringBuilder,拼接字符串100000次,花费36秒

Although there is a difference, the difference is very small. Considering that it has been executed 100,000 times, the difference in time-consuming each time is even smaller. Moreover, there are various factors affecting the execution efficiency of program execution, so it can be considered that the time-consuming is about the same. You can also perform it multiple times to compare the time-consuming differences, and you can also find that they are basically consistent.

Go to the directory where the class file is located and execute javap -c StringTest.class to decompile the class file and check the compiled code differences. Do not use Intellij idea and JD to decompile here, because decompilation is optimized and will be decompiled into "+" splicing, and the real situation after compilation cannot be seen.

It can be seen from the figure that the two splicing methods are exactly the same after decompilation, there is no difference, and the execution efficiency is naturally the same.

Since the execution efficiency is the same, it is recommended to use "+" to splice strings for the sake of concise code and easier reading.

2. Loop splicing

When splicing a long string in a loop, it is recommended to use StringBuilder. Although the "+" spliced ​​string will become a StringBuilder after compilation, a new StringBuilder object will be created each time the loop is processed, which will greatly increase the time consumption. When using StringBuilder directly, just use new once, which is relatively efficient.

Add 2 new Junit test cases, loop splicing 10,000 times to splice a string (the number of times is less than the above use case, because it is spliced ​​into a string, and if the number of splicing times is too many, it may cause memory overflow):

/**
 * 循环使用+拼接字符串
 */
@Test
public void testLoopStringConcatenation03ByPlus() {
    long startTime = System.currentTimeMillis();
    int count = 10000;
    String str = "testLoopStringConcatenation03ByPlus:";
    for (int i = 0; i < count; i++) {
        str = str + "-" + i;
    }
    System.out.println(str);
    long endTime = System.currentTimeMillis();
    System.out.println("testLoopStringConcatenation03ByPlus,拼接字符串" + count + "次,花费" + (endTime - startTime) + "秒");
}

/**
 * 测试循环使用StringBuilder拼接字符串耗时
 */
@Test
public void testLoopStringConcatenation04ByStringBuilder() {
    long startTime = System.currentTimeMillis();
    int count = 100000;
    StringBuilder stringBuilder = new StringBuilder("testLoopStringConcatenation04ByStringBuilder:");
    for (int i = 0; i < count; i++) {
        stringBuilder.append("-");
        stringBuilder.append(i);
    }
    String str = stringBuilder.toString();
    System.out.println(str);
    long endTime = System.currentTimeMillis();
    System.out.println("testLoopStringConcatenation04ByStringBuilder,拼接字符串" + count + "次,花费" + (endTime - startTime) + "秒");
}

Execute the Junit use case and see the time-consuming statistics output:

testLoopStringConcatenation03ByPlus,拼接字符串10000次,花费463秒
testLoopStringConcatenation04ByStringBuilder,拼接字符串10000次,花费13秒

It can be seen that the difference is obvious and not of the same magnitude.

Summarize

  1. Simple string concatenation uses "+", which is faster and more concise.
  2. When splicing in a loop, using "+" to splice strings is inefficient. It is recommended to use StringBuilder.

Recommended recent popular articles:

1.1,000+ Java interview questions and answers (2022 latest version)

2.Excellent! Java coroutines are coming. . .

3.Spring Boot 2.x tutorial, so complete!

4.Stop filling the screen with explosions and explosions. Try the decorator mode. This is the elegant way! !

5."Java Development Manual (Songshan Edition)" is newly released, download it quickly!

If you think it’s good, don’t forget to like and retweet!

Guess you like

Origin blog.csdn.net/youanyyou/article/details/134641112
Recommended