Hello everyone , I'm fried fish .
Go1.18 In a few weeks (3 month ) It's about to be released , Previously, we have updated several issues of new version features , Today I'll bring you a new optimization class , Is with the strings and bytes Standard library .
background
Want to copy faster
In everyday programming , byte []byte It is often copied . You need to write the following code :
dup := make([]byte, len(data))
copy(dup, data)@Ilia Choly I think it's too troublesome , After all, I have to write it every time , Or encapsulate it into the following functions :
// Clone returns a copy of b
func Clone(b []byte) []byte {
b2 := make([]byte, len(b))
copy(b2, b)
return b2
}To do this, I want to add a shortcut , But this obviously doesn't hold water , Students will find a ready-made way to be familiar with grammar :
b2 := append([]byte(nil), b...)One line can achieve the effect , Even faster , Because the allocated slice will not be initialized to zero .
Copying will share memory
many Go developer , When writing an application, copy the slice (Slice) when , You'll find the copied slices s1 And the original s0 There are memory associations , Its essential reason lies in its underlying data structure , This can lead to many hidden problems .
The sample code is as follows :
import (
"fmt"
"reflect"
"unsafe"
)
func main() {
s0 := " I have fried fish in my head "
s1 := s0[:3]
s0h := (*reflect.StringHeader)(unsafe.Pointer(&s0))
s1h := (*reflect.StringHeader)(unsafe.Pointer(&s1))
fmt.Printf("Len is equal: %t\n", s0h.Len == s1h.Len)
fmt.Printf("Data is equa: %t\n", s0h.Data == s1h.Data)
}From the above procedure , What do you think of variables s0 and s1 comparison , their Len Is it equal ?Data Is it equal ?
The output is as follows :
Len is equal: false
Data is equa: trueWhat do you think , That seems fine .Len It's not equal , After all, it is copied by index . but Data It's equal , Why , yes Go Out BUG Did you? ?
This is actually related to Go stay String and Slice Related to the underlying data structure , for example String The runtime performance of is StringHeader.
His underlying structure is as follows :
type StringHeader struct {
Data uintptr
Len int
}- Data: Point to the specific underlying array .
- Len: Represents the length of the string slice .
The point is Data, A pointer to the underlying data is essentially an address , Therefore, when copying , It will also be copied . Causing unnecessary duplication and “ dirty ” data , Cause all kinds of strange BUG.
This problem , Pain points of new features .
New characteristics
stay Go1.18 Among the new features of ,strings and bytes Added one Clone Method , To solve the problems mentioned earlier 2 There are two problems .
The source code is as follows :
func Clone(s string) string {
if len(s) == 0 {
return ""
}
b := make([]byte, len(s))
copy(b, s)
return *(*string)(unsafe.Pointer(&b))
}- adopt
copyFunction to copy the original string , Get a new one[]bytedata . - adopt
*(*string)(unsafe.Pointer(&b))Pointer operation , RealizationbyteTostringMemory zero conversion .
thus , Two problems in the background are solved in a very clever way . You don't have to write similar code all the time .
summary
all the time ,Go Medium string and slice It is controversial because of the underlying array pointing and capacity expansion mechanism , At the end, we also give some of the official account numbers before. “ pit ”, Interested readers can have a look at .
this 1.18 New method update , It has a certain function , You can also know clearly in your study Clone His role and definition , Keep an eye on it .
Do you have similar code in your project ?
If you have any questions, you are welcome to feedback and exchange in the comments area , The best relationship is mutual achievement , Everyone give the thumbs-up Namely Fried fish The greatest power of creation , Thank you for your support .
Articles are constantly updated , You can search through wechat 【 I have fried fish in my head 】 read , this paper GitHubgithub.com/eddycjy/blog Included , Study Go Language can be seen Go Learn maps and routes , welcome Star Hurry up .
Previous recommendation
Reference resources
- bytes, strings: add Clone
- [test: add test that we don't optimize string([]byte(string))](https://github.com/golang/go/...)
- proposal: provide std lib pkg Clone function to copy a string efficiently without memory sharing


![leetcode:55. Jumping game [classic greed]](/img/da/16e4ab51320d68bd1ade0eb0a2dbc2.png)






