github.com/lxt1045/json@v0.0.0-20231013032136-54d6b1d6e525/api_bench_test.go (about)

     1  package json
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  	"unsafe"
     7  
     8  	lxterrs "github.com/lxt1045/errors"
     9  )
    10  
    11  func BenchmarkLoadTagNode(b *testing.B) {
    12  	in := &J0{}
    13  	// 解引用; TODO: 用 Value 的方式提高性能
    14  	vi := reflect.Indirect(reflect.ValueOf(in))
    15  	if !vi.CanSet() {
    16  		b.Fatal("err")
    17  	}
    18  	prv := reflectValueToValue(&vi)
    19  	goType := prv.typ
    20  	tag, err := LoadTagNode(vi, goType.Hash)
    21  	if err != nil {
    22  		return
    23  	}
    24  	_ = tag
    25  	b.Run("LoadTagNode", func(b *testing.B) {
    26  		b.ReportAllocs()
    27  		for i := 0; i < b.N; i++ {
    28  			tag, err = LoadTagNode(vi, goType.Hash)
    29  		}
    30  		b.SetBytes(int64(b.N))
    31  		b.StopTimer()
    32  	})
    33  
    34  	b.Run("LoadTagNodeSlow", func(b *testing.B) {
    35  		b.ReportAllocs()
    36  		for i := 0; i < b.N; i++ {
    37  			tag, err = LoadTagNodeSlow(vi.Type(), goType.Hash)
    38  		}
    39  		b.SetBytes(int64(b.N))
    40  		b.StopTimer()
    41  	})
    42  }
    43  
    44  func BenchmarkIF(b *testing.B) {
    45  	b.Run("IF 1", func(b *testing.B) {
    46  		b.ReportAllocs()
    47  		stream0 := []byte("true,false,true")
    48  		stream := stream0
    49  		result := false
    50  		for i := 0; i < b.N; i++ {
    51  			if stream[0] == 't' && stream[1] == 'r' && stream[2] == 'u' && stream[3] == 'e' {
    52  				stream = stream[5:]
    53  				result = true
    54  			} else if stream[0] == 'f' && stream[1] == 'a' && stream[2] == 'l' && stream[3] == 's' && stream[4] == 'e' {
    55  				stream = stream0
    56  				result = false
    57  			} else {
    58  				err := lxterrs.New("should be \"false\" or \"true\", not [%s]", ErrStream(string(stream)))
    59  				panic(err)
    60  			}
    61  		}
    62  		_ = result
    63  		b.SetBytes(int64(b.N))
    64  		b.StopTimer()
    65  	})
    66  	b.Run("IF 2", func(b *testing.B) {
    67  		b.ReportAllocs()
    68  		stream0 := []byte("true,false,true")
    69  		iTrue := *(*uint64)(unsafe.Pointer(&([]byte("true")[0]))) & 0x00000000ffffffff
    70  		iFalse := *(*uint64)(unsafe.Pointer(&([]byte("false")[0]))) & 0x000000ffffffffff
    71  		stream := stream0
    72  		result := false
    73  		for i := 0; i < b.N; i++ {
    74  			if x := *(*uint64)(unsafe.Pointer(&stream[0])) & 0x00000000ffffffff; x == iTrue {
    75  				stream = stream[5:]
    76  				result = true
    77  			} else if y := *(*uint64)(unsafe.Pointer(&stream[0])) & 0x000000ffffffffff; y == iFalse {
    78  				stream = stream0
    79  				result = false
    80  			} else {
    81  				err := lxterrs.New("should be \"false\" or \"true\", not [%s]", ErrStream(string(stream)))
    82  				panic(err)
    83  			}
    84  		}
    85  		_ = result
    86  		b.SetBytes(int64(b.N))
    87  		b.StopTimer()
    88  	})
    89  }