Why does BenchmarkTest3 in go 1.22 still have memory allocation? My local 
test doesn’t have it

在2023年11月27日星期一 UTC+8 23:14:03<peterGo> 写道:

>
> 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 golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/2b93d4aa-1aca-4da9-93cb-bf836b250b6bn%40googlegroups.com.

Reply via email to