String Splicing Definition
Define a method that implements string splicing, with the following function signature prototype.
|
|
That is, pass in a series of strings and return the result of their stitching.
Way 1: Use the + operator
Obviously, the performance of this approach is poor.
The underlying layer of string is a StringHeader. therefore, strings are immutable in golang, which leads to the summation process of a string creating a whole new variable to receive the spliced string. So it is not optimal in terms of number of memory allocations and time efficiency.
Way 2: Use fmt.Sprintf()
fmt.Sprintf itself is used for formatting, so it does a lot more than just splicing, such as parsing placeholders. Although it uses an []byte array at the bottom to store the data, its overall performance is worse than using + directly. So fmt.Spritf() is not recommended when it comes to simply splicing strings.
Way 3: Use strings.Buider
The underlying strings.Buider also uses []byte arrays, and it is exclusively responsible for splicing, so its performance in terms of time efficiency and memory operations is better. And the array is expanded by a fixed number of times (2x and 1.25x), so it can also largely reduce the number of memory requests in frequent splicing scenarios.
Way 4: Use strings.Join()
The underlying strings.Join also uses the []byte array, but it also splices in an extra delimiter, so it will still splice in an extra empty string if the delimiter is not needed, so its performance is not as high as strings.Builder.
Way 5: Use bytes.Buffer
The underlying bytes.Buffer is still a []byte array, but a big difference between it and strings.Builder is that when calling b.String(), it reapplies memory again, and then assigns the result to the newly applied memory. The String() method of strings.Buider returns the underlying []byte array directly, so this extra layer of operation in bytes.Buffer makes its performance inferior to that of strings.Buidler.
Performance Testing
From the above analysis of the underlying data types, we can roughly know the advantages and disadvantages of different splicing methods in string splicing scenarios.
|
|
The benchmark test is executed and the results are as follows.
|
|
Conclusion
- String is a read-only literal in Golang. To improve the performance of string splicing, we need to reduce its memory allocation number, memory allocation size, etc.
- Directly using
+to splice strings creates new strings frequently to save the result of one splice, and n splices require creating n new strings of increasing size, so its performance is low. - In addition to using
+directly, others such asfmt.Sprintf(),strings.Builder,bytes.Bufferall use[]bytearrays to store data, and the array-based expansion method can reduce the number of new memory requests during splicing and no extra duplicate space, thus improving the performance of splicing . fmt.Sprintfandstrings.Joinboth do a lot of extra work, such as placeholder parsing, delimiter splicing, etc., which are the reasons why it is less efficient thanstrings.Buidler.- The performance of
strings.Buidlerandbyte.Bufferis relatively good, with a single job duty, so the performance is better. Butbytes.Bufferwill have one extra memory request and assignment job, so its performance is lower thanstrings.Builder.