<>1. Use operators directly
func BenchmarkAddStringWithOperator(b *testing.B) { hello := "hello" world :=
"world" for i := 0; i < b.N; i++ { _ = hello + "," + world } }
golang The strings are immutable , Each operation produces a new string , So a lot of temporary useless strings will be generated , It's not only useless , I'll give it to you gc
Bring extra burden , So the performance is poor

<>2. fmt.Sprintf()
func BenchmarkAddStringWithSprintf(b *testing.B) { hello := "hello" world :=
"world" for i := 0; i < b.N; i++ { _ = fmt.Sprintf("%s,%s", hello, world) } }
Internal use []byte realization , Unlike the direct operator, it produces a lot of temporary strings , But the internal logic is complex , There's a lot of extra judgment , It's also used
interface, So the performance is not very good

<>3. strings.Join()
func BenchmarkAddStringWithJoin(b *testing.B) { hello := "hello" world :=
"world" for i := 0; i < b.N; i++ { _ = strings.Join([]string{hello, world},
",") } }

join First, according to the contents of the string array , Calculate the length of a splice , Then apply for the corresponding size of memory , Fill in one string at a time , If there is already an array , This kind of efficiency will be very high , But it didn't , The cost of constructing this data is not small

<>4. buffer.WriteString()
func BenchmarkAddStringWithBuffer(b *testing.B) { hello := "hello" world :=
"world" for i := 0; i < 1000; i++ { var buffer bytes.Buffer
buffer.WriteString(hello) buffer.WriteString(",") buffer.WriteString(world) _ =
buffer.String() } }
This is ideal , It can be used as a variable character , It also optimizes the growth of memory , If you can estimate the length of the string , It's still working buffer.Grow() Interface capacity

Technology