Assigning Benchmark results to package variables:
var (
str string
byt []byte
)
BenchmarkString
str = string(byteSli)
BenchmarkUnsafe
str = *(*string)(unsafe.Pointer(&byteSli))
BenchmarkByteStyle
byt = []byte(str)
BenchmarkWithUnsafe
byt = *(*[]byte)(unsafe.Pointer(&bh))
$ go1.21 test nuts_test.go -run=! -bench=. -benchmem
BenchmarkTest1-12 22507272 50.72 ns/op 192 B/op 1 allocs/op
BenchmarkTest2-12 27105592 49.92 ns/op 192 B/op 1 allocs/op
BenchmarkTest3-12 25006983 41.32 ns/op 160 B/op 1 allocs/op
BenchmarkTest4-12 1000000000 1.158 ns/op 0 B/op 0 allocs/op
$ go1.22 test nuts_test.go -run=! -bench=. -benchmem
BenchmarkTest1-12 17386624 65.79 ns/op 192 B/op 1 allocs/op
BenchmarkTest2-12 18603463 62.30 ns/op 192 B/op 1 allocs/op
BenchmarkTest3-12 23741634 57.76 ns/op 160 B/op 1 allocs/op
BenchmarkTest4-12 1000000000 1.157 ns/op 0 B/op 0 allocs/op
peter
On Monday, November 27, 2023 at 7:12:54 AM UTC-5 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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/golang-nuts/d916ad76-f9cb-4924-89cd-04259262f64cn%40googlegroups.com.