This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
XDM, we all know that Golang is inherently a highly concurrent, highly efficient compiled language
However, we all know that no matter how good the tool is, it is useless to use it incorrectly. Let’s give two common paths to experience it
Struct and map?
The time difference between using temporary structs and maps may not be noticeable when the amount of computation is small, but it becomes obvious when the number increases, and the difference becomes more obvious as the number increases
When we get to the point where both keys and values can be fixed, we choose structs much more efficiently than we choose maps
- We ran a simulation loop 100 million times to see how long it would take to use each data structure
- Calculate the current time before loop
- After the loop, calculate the current time
- Finally, calculate the difference between the two times, where we use milliseconds
func main(a) {
t1 :=time.Now().UnixNano()/1e6
for i := 0; i < 100000000; i++ {
var test struct {
Name string
hobby string
}
test.Name = "xiaomotong"
test.hobby = "program"
}
t2 :=time.Now().UnixNano()/1e6
fmt.Println("t2 - t1 == ", t2-t1)
}
Copy the code
Run the program to view the effect:
# go run main.go
t1 == 1634377149185
t2 == 1634377149221
t2 - t1 == 36
Copy the code
Using struct mode, it takes 36 ms, how do you feel about this time?
Let’s take a look at using Map
func main(a) {
t1 :=time.Now().UnixNano()/1e6
fmt.Println("t1 == ", t1)
for i := 0; i < 100000000; i++ {
var test = map[string]interface{}{}
test["name"] = "xiaomotong"
test["hobby"] = "program"
}
t2 :=time.Now().UnixNano()/1e6
fmt.Println("t2 == ", t2)
fmt.Println("t2 - t1 == ", t2-t1)
}
Copy the code
Run the program to view the effect:
# go run main.go
t1 == 1634377365927
t2 == 1634377373525
t2 - t1 == 7598
Copy the code
Using struct mode, it takes 7598 ms
Using map and struct to complete the same data processing, the time difference is 212 times, just this, when we usually code, for the above scenario, which data structure do you choose?
Why is the gap so large
In cases where we can determine fields, we use temporary structs that don’t need to dynamically allocate content at run time,
A map, on the other hand, has to check the index, which can be very time-consuming
How to concatenate strings?
Encoding XDM in the work encountered string concatenation, how to achieve it? Our tools are temporarily provided as follows:
- use
+
The way of - use
fmt.Sprintf()
The way of - use
strings.Join
The way of - use
buffer
The way of
Now, maybe we have different answers, but let’s just do it, and see how long it takes them to process the same string concatenation
with+
The way of
- Let’s loop through appending the string 500,000 times to see how long it takes
func main(a) {
t1 := time.Now().UnixNano() / 1e6
fmt.Println("t1 == ", t1)
s := "xiao"
for i := 0; i < 500000; i++ {
s += "motong"
}
t2 := time.Now().UnixNano() / 1e6
fmt.Println("t2 == ", t2)
fmt.Println("t2 - t1 == ", t2-t1)
}
Copy the code
Run the program to view the effect:
# go run main.go
t1 == 1634378595642
t2 == 1634378743119
t2 - t1 == 147477
Copy the code
XDM is surprised at how slow it is, 147477 ms, which is 2 minutes and 27 seconds
The use of + to process strings in The Go language is performance-intensive, as we can see from the data
usefmt.Sprintf()
The way of
func main(a) {
t1 := time.Now().UnixNano() / 1e6
fmt.Println("t1 == ", t1)
s := "xiao"
for i := 0; i < 500000; i++ {
s = fmt.Sprintf("%s%s",s,"motong")
}
t2 := time.Now().UnixNano() / 1e6
fmt.Println("t2 == ", t2)
fmt.Println("t2 - t1 == ", t2-t1)
}
Copy the code
Run the program to view the effect:
# go run main.go
t1 == 1634378977361
t2 == 1634379240292
t2 - t1 == 262931
Copy the code
It took 262,931 ms, 4 minutes and 22 seconds. XDM didn’t realize that FMT.Sprintf was slower than +
usestrings.Join
The way of
func main(a) {
t1 := time.Now().UnixNano() / 1e6
fmt.Println("t1 == ", t1)
s := "xiao"
for i := 0; i < 500000; i++ {
s = strings.Join([]string{s,"motong"},"")
}
t2 := time.Now().UnixNano() / 1e6
fmt.Println("t2 == ", t2)
fmt.Println("t2 - t1 == ", t2-t1)
}
Copy the code
Run the program to view the effect:
# go run main.go
t1 == 1634379455304
t2 == 1634379598227
t2 - t1 == 142923
Copy the code
It took 142,923 ms, with a total of 2 minutes and 22 seconds, similar to using +
usebuffer
The way of
Using buffer is probably the best way to do it,
func main(a) {
t1 := time.Now().UnixNano() / 1e6
fmt.Println("t1 == ", t1)
s := bytes.NewBufferString("xiao")
for i := 0; i < 500000; i++ {
s.WriteString("motong")
}
t2 := time.Now().UnixNano() / 1e6
fmt.Println("t2 == ", t2)
fmt.Println("t2 - t1 == ", t2-t1)
}
Copy the code
# go run main.go
t1 == 1634378506021
t2 == 1634378506030
t2 - t1 == 9
Copy the code
From the above data, we see that the same data is spliced together 500,000 times
- First, use
+
The way that needs to be147477 ms - Second, use
fmt.Sprintf()
The way that needs to be262931 ms - Third, use
strings.Join
The way that needs to be142923 ms - Fourth, use
buffer
The way that needs to be9ms
The method of using buffer is 16,386 times more than the first method, 29,214 times more than the second method, and 15,880 times more than the third method
XDM, if you encounter the above scenario, which way would you choose to use? The comments section can discuss together, whether there is a more efficient way
Welcome to like, follow and favorites
Friends, your support and encouragement, I insist on sharing, improve the quality of the power
All right, that’s it for this time
Technology is open, our mentality, should be more open. Embrace change, live in the sun, and strive to move forward.
I am Nezha, welcome to like, see you next time ~