See https://github.com/golang/go/issues/2205 The tip compiler is able to detect some simple string->[]byte cases in which duplication is not needed.
On Monday, November 27, 2023 at 8:12:54 PM UTC+8 fliter wrote: > It seems that go 1.22 has optimized the implementation of string to byte > slicing and no longer requires memory allocation. > > > But why not optimize byte slicing to string conversion together? > > > ```go > package main > > import ( > "reflect" > "testing" > "unsafe" > ) > > > func BenchmarkString(b *testing.B) { > byteSli := []byte{123, 34, 100, 101, 102, 97, 117, 108, 116, 34, 58, 123, > 34, 99, 111, 109, 109, 111, 110, 34, 58, 123, 34, 112, 101, 116, 34, 58, > 123, 34, 102, 105, 118, 101, 34, 58, 34, 230, 150, 145, 230, 150, 145, 34, > 44, 34, 102, 111, 117, 114, 34, 58, 34, 231, 154, 174, 231, 147, 156, 231, > 147, 156, 34, 44, 34, 111, 110, 101, 34, 58, 34, 229, 188, 165, 229, 188, > 165, 230, 135, 181, 34, 44, 34, 116, 104, 114, 101, 101, 34, 58, 34, 229, > 145, 134, 229, 145, 134, 34, 44, 34, 116, 119, 111, 34, 58, 34, 233, 187, > 132, 230, 169, 153, 230, 169, 153, 34, 125, 44, 34, 114, 101, 108, 97, 116, > 105, 111, 110, 34, 58, 123, 34, 102, 97, 116, 104, 101, 114, 34, 58, 34, > 99, 117, 105, 120, 120, 120, 120, 120, 120, 120, 34, 44, 34, 109, 111, 116, > 104, 101, 114, 34, 58, 34, 121, 105, 110, 120, 120, 120, 120, 120, 34, 44, > 34, 119, 105, 102, 101, 34, 58, 34, 112, 101, 110, 103, 120, 120, 34, 125, > 125, 125, 125} > > _ = string(byteSli) > > } > > func BenchmarkUnsafe(b *testing.B) { > byteSli := []byte{123, 34, 100, 101, 102, 97, 117, 108, 116, 34, 58, 123, > 34, 99, 111, 109, 109, 111, 110, 34, 58, 123, 34, 112, 101, 116, 34, 58, > 123, 34, 102, 105, 118, 101, 34, 58, 34, 230, 150, 145, 230, 150, 145, 34, > 44, 34, 102, 111, 117, 114, 34, 58, 34, 231, 154, 174, 231, 147, 156, 231, > 147, 156, 34, 44, 34, 111, 110, 101, 34, 58, 34, 229, 188, 165, 229, 188, > 165, 230, 135, 181, 34, 44, 34, 116, 104, 114, 101, 101, 34, 58, 34, 229, > 145, 134, 229, 145, 134, 34, 44, 34, 116, 119, 111, 34, 58, 34, 233, 187, > 132, 230, 169, 153, 230, 169, 153, 34, 125, 44, 34, 114, 101, 108, 97, 116, > 105, 111, 110, 34, 58, 123, 34, 102, 97, 116, 104, 101, 114, 34, 58, 34, > 99, 117, 105, 120, 120, 120, 120, 120, 120, 120, 34, 44, 34, 109, 111, 116, > 104, 101, 114, 34, 58, 34, 121, 105, 110, 120, 120, 120, 120, 120, 34, 44, > 34, 119, 105, 102, 101, 34, 58, 34, 112, 101, 110, 103, 120, 120, 34, 125, > 125, 125, 125} > > _ = *(*string)(unsafe.Pointer(&byteSli)) > } > > func BenchmarkByteStyle(b *testing.B) { > > str := > `{"default":{"common":{"pet":{"five":"aa","four":"bb","one":"cc","three":"dd","two":"黄ee"},"relation":{"father":"ff","mother":"mm","wife":"ww"}}}}` > > _ = []byte(str) > > } > > func BenchmarkWithUnsafe(b *testing.B) { > > str > := > `{"default":{"common":{"pet":{"five":"aa","four":"bb","one":"cc","three":"dd","two":"黄ee"},"relation":{"father":"ff","mother":"mm","wife":"ww"}}}}` > > sh := (*reflect.StringHeader)(unsafe.Pointer(&str)) > bh := reflect.SliceHeader{ > Data: sh.Data, > Len: sh.Len, > Cap: sh.Len, > } > _ = *(*[]byte)(unsafe.Pointer(&bh)) > > } > ``` > > ```bench_test.go > package main > > import ( > "testing" > ) > > > func BenchmarkTest1(b *testing.B) { > for i := 0; i < b.N; i++ { > BenchmarkString(b) > } > } > > func BenchmarkTest2(b *testing.B) { > for i := 0; i < b.N; i++ { > BenchmarkUnsafe(b) > } > } > > func BenchmarkTest3(b *testing.B) { > for i := 0; i < b.N; i++ { > BenchmarkByteStyle(b) > } > } > > func BenchmarkTest4(b *testing.B) { > for i := 0; i < b.N; i++ { > BenchmarkWithUnsafe(b) > } > } > ``` > > when go version is 1.21 > > ```shell > go version > go version go1.21.0 darwin/arm64 > > goos: darwin > goarch: arm64 > pkg: bc > BenchmarkTest1-8 37078008 32.45 ns/op 192 > B/op 1 allocs/op > BenchmarkTest2-8 144106840 9.181 ns/op 0 > B/op 0 allocs/op > BenchmarkTest3-8 38973375 28.94 ns/op 192 > B/op 1 allocs/op > BenchmarkTest4-8 1000000000 0.3130 ns/op 0 > B/op 0 allocs/op > PASS > ok bc 6.038s > > ``` > > > > when go version is 1.22 > > ```shell > go version > go version devel go1.22-631a6c2abf Fri Nov 17 23:34:11 2023 +0000 > darwin/arm64 > > > go test -test.bench=".*" -benchmem > goos: darwin > goarch: arm64 > pkg: bc > BenchmarkTest1-8 35727334 33.51 ns/op 192 > B/op 1 allocs/op > BenchmarkTest2-8 147172425 8.157 ns/op 0 > B/op 0 allocs/op > BenchmarkTest3-8 1000000000 0.3136 ns/op 0 > B/op 0 allocs/op > BenchmarkTest4-8 1000000000 0.3153 ns/op 0 > B/op 0 allocs/op > PASS > ok bc 5.095s > ``` > > > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/15dbb33b-5015-4220-80f1-a47524421a8fn%40googlegroups.com.