github.com/GuanceCloud/cliutils@v1.1.21/point/decode_test.go (about)

     1  // Unless explicitly stated otherwise all files in this repository are licensed
     2  // under the MIT License.
     3  // This product includes software developed at Guance Cloud (https://www.guance.com/).
     4  // Copyright 2021-present Guance, Inc.
     5  
     6  package point
     7  
     8  import (
     9  	"bytes"
    10  	"fmt"
    11  	"strings"
    12  	T "testing"
    13  	"time"
    14  
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestLPFieldArray(t *T.T) {
    20  	t.Run(`decode-lp-array-field`, func(t *T.T) {
    21  		lp := []byte(`a,t1=v1 arr=["s1","s2"] 123`)
    22  
    23  		dec := GetDecoder(WithDecEncoding(LineProtocol))
    24  		_, err := dec.Decode(lp)
    25  		assert.NoErrorf(t, err, "should got no error: %s", err)
    26  	})
    27  
    28  	t.Run(`encode-lp-array-field`, func(t *T.T) {
    29  		pt := emptyPoint()
    30  
    31  		pt.SetName("abc")
    32  		pt.SetTime(time.Unix(0, 123))
    33  
    34  		pt.AddKVs(NewKV("i-arr", []int{1, 2, 3}))
    35  		pt.AddKVs(NewKV("s-arr", []string{"hello", "world"}))
    36  		pt.AddKVs(NewKV("f-arr", []float64{3.14, 6.18}))
    37  		pt.AddKVs(NewKV("b-arr", []bool{false, true}))
    38  
    39  		t.Logf("lp: %s", pt.LineProto())
    40  	})
    41  
    42  	t.Run(`encode-json-array-field`, func(t *T.T) {
    43  		pt := emptyPoint()
    44  
    45  		pt.SetName("abc")
    46  		pt.SetTime(time.Unix(0, 123))
    47  
    48  		pt.AddKVs(NewKV("i-arr", []int{1, 2, 3}))
    49  		pt.AddKVs(NewKV("s-arr", []string{"hello", "world"}))
    50  		pt.AddKVs(NewKV("f-arr", []float64{3.14, 6.18}))
    51  		pt.AddKVs(NewKV("b-arr", []bool{false, true}))
    52  
    53  		enc := GetEncoder(WithEncEncoding(JSON))
    54  		defer PutEncoder(enc)
    55  
    56  		arr, err := enc.Encode([]*Point{pt})
    57  		assert.NoError(t, err)
    58  
    59  		t.Logf("lp json: %s", string(arr[0]))
    60  	})
    61  
    62  	t.Run(`decode-json-array-field`, func(t *T.T) {
    63  		j := `[{"measurement":"abc","fields":{"b-arr":[false,true],"f-arr":[3.14,6.18],"i-arr":[1,2,3],"s-arr":["hello","world"]},"time":123}]`
    64  		dec := GetDecoder(WithDecEncoding(JSON))
    65  		defer PutDecoder(dec)
    66  
    67  		pts, err := dec.Decode([]byte(j))
    68  		assert.NoError(t, err)
    69  
    70  		for _, pt := range pts {
    71  			t.Logf("json pt: %s", pt.LineProto())
    72  		}
    73  	})
    74  }
    75  
    76  func TestTimeRound(t *T.T) {
    77  	t.Run(`decode-time`, func(t *T.T) {
    78  		pt := NewPointV2("some", nil, WithTime(time.Now()))
    79  		enc := GetEncoder(WithEncEncoding(Protobuf))
    80  		data, err := enc.Encode([]*Point{pt})
    81  		assert.NoError(t, err)
    82  
    83  		dec := GetDecoder(WithDecEncoding(Protobuf))
    84  		pts, err := dec.Decode(data[0])
    85  		assert.NoError(t, err)
    86  
    87  		assert.Equal(t, pt.Pretty(), pts[0].Pretty())
    88  	})
    89  }
    90  
    91  func TestDynamicPrecision(t *T.T) {
    92  	pts := []*Point{
    93  		func() *Point {
    94  			var kvs KVs
    95  			kvs = kvs.AddV2("f1", 123, true)
    96  			return NewPointV2("p1", kvs, WithTimestamp(1716536956))
    97  		}(),
    98  
    99  		func() *Point {
   100  			var kvs KVs
   101  			kvs = kvs.AddV2("f1", 123, true)
   102  			return NewPointV2("p1", kvs, WithTimestamp(1716536956000))
   103  		}(),
   104  
   105  		func() *Point {
   106  			var kvs KVs
   107  			kvs = kvs.AddV2("f1", 123, true)
   108  			return NewPointV2("p1", kvs, WithTimestamp(1716536956000000))
   109  		}(),
   110  
   111  		func() *Point {
   112  			var kvs KVs
   113  			kvs = kvs.AddV2("f1", 123, true)
   114  			return NewPointV2("p1", kvs, WithTimestamp(1716536956000000000))
   115  		}(),
   116  	}
   117  
   118  	cases := []struct {
   119  		name string
   120  		e    Encoding
   121  	}{
   122  		{
   123  			"line-protocol",
   124  			LineProtocol,
   125  		},
   126  
   127  		//{
   128  		//	"json",
   129  		//	JSON,
   130  		// },
   131  
   132  		//{
   133  		//	"pbjson",
   134  		//	PBJSON,
   135  		// },
   136  
   137  		{
   138  			"pb",
   139  			Protobuf,
   140  		},
   141  	}
   142  
   143  	for _, tc := range cases {
   144  		t.Run(tc.name, func(t *T.T) {
   145  			enc := GetEncoder(WithEncEncoding(tc.e))
   146  			defer PutEncoder(enc)
   147  
   148  			enc.EncodeV2(pts)
   149  			buf := make([]byte, 1<<20) // large buffer
   150  			var (
   151  				encBuf []byte
   152  				ok     bool
   153  			)
   154  
   155  			encBuf, ok = enc.Next(buf) // encode once we should get all the buffer
   156  			assert.True(t, ok, "enc last error: %s", enc.LastErr())
   157  
   158  			dec := GetDecoder(WithDecEncoding(tc.e))
   159  			defer PutDecoder(dec)
   160  
   161  			newPts, err := dec.Decode(encBuf, WithPrecision(PrecDyn))
   162  			assert.NoError(t, err)
   163  			for _, pt := range newPts {
   164  				assert.Equal(t, int64(1716536956000000000), pt.pt.Time)
   165  			}
   166  		})
   167  	}
   168  }
   169  
   170  func TestDecode(t *T.T) {
   171  	var fnCalled int
   172  
   173  	cases := []struct {
   174  		name     string
   175  		data     []byte
   176  		fn       DecodeFn
   177  		fnErr    bool
   178  		expectLP []string
   179  
   180  		opts    []DecoderOption
   181  		ptsOpts []Option
   182  
   183  		fail bool
   184  	}{
   185  		{
   186  			name: "decode-json",
   187  			data: []byte(`[ { "measurement": "abc",  "tags": {"t1": "val1"}, "fields": {"f1": 123, "f2": 3.14}, "time":123} ]`),
   188  			expectLP: []string{
   189  				`abc,t1=val1 f1=123,f2=3.14 123`,
   190  			},
   191  
   192  			opts: []DecoderOption{WithDecEncoding(JSON)},
   193  		},
   194  
   195  		{
   196  			name: "decode-json-with-precision-s",
   197  			data: []byte(`[ { "measurement": "abc",  "tags": {"t1": "val1"}, "fields": {"f1": 123, "f2": 3.14}, "time":123} ]`),
   198  			expectLP: []string{
   199  				`abc,t1=val1 f1=123,f2=3.14 123000000000`,
   200  			},
   201  
   202  			opts:    []DecoderOption{WithDecEncoding(JSON)},
   203  			ptsOpts: []Option{WithPrecision(PrecS)},
   204  		},
   205  
   206  		{
   207  			name: "decode-json-with-precision-ms",
   208  			data: []byte(`[ { "measurement": "abc",  "tags": {"t1": "val1"}, "fields": {"f1": 123, "f2": 3.14}, "time":123} ]`),
   209  			expectLP: []string{
   210  				`abc,t1=val1 f1=123,f2=3.14 123000000`,
   211  			},
   212  
   213  			opts:    []DecoderOption{WithDecEncoding(JSON)},
   214  			ptsOpts: []Option{WithPrecision(PrecMS)},
   215  		},
   216  
   217  		{
   218  			name: "decode-json-with-precision-us",
   219  			data: []byte(`[ { "measurement": "abc",  "tags": {"t1": "val1"}, "fields": {"f1": 123, "f2": 3.14}, "time":123} ]`),
   220  			expectLP: []string{
   221  				`abc,t1=val1 f1=123,f2=3.14 123000`,
   222  			},
   223  
   224  			opts:    []DecoderOption{WithDecEncoding(JSON)},
   225  			ptsOpts: []Option{WithPrecision(PrecUS)},
   226  		},
   227  
   228  		{
   229  			name: "decode-json-with-precision-m",
   230  			data: []byte(`[ { "measurement": "abc",  "tags": {"t1": "val1"}, "fields": {"f1": 123, "f2": 3.14}, "time":123} ]`),
   231  			expectLP: []string{
   232  				`abc,t1=val1 f1=123,f2=3.14 7380000000000`,
   233  			},
   234  
   235  			opts:    []DecoderOption{WithDecEncoding(JSON)},
   236  			ptsOpts: []Option{WithPrecision(PrecM)},
   237  		},
   238  
   239  		{
   240  			name: "decode-json-with-precision-h",
   241  			data: []byte(`[ { "measurement": "abc",  "tags": {"t1": "val1"}, "fields": {"f1": 123, "f2": 3.14}, "time":123} ]`),
   242  			expectLP: []string{
   243  				`abc,t1=val1 f1=123,f2=3.14 442800000000000`,
   244  			},
   245  
   246  			opts:    []DecoderOption{WithDecEncoding(JSON)},
   247  			ptsOpts: []Option{WithPrecision(PrecH)},
   248  		},
   249  
   250  		{
   251  			name: "decode-json-with-precision-x",
   252  			data: []byte(`[ { "measurement": "abc",  "tags": {"t1": "val1"}, "fields": {"f1": 123, "f2": 3.14}, "time":123} ]`),
   253  			expectLP: []string{
   254  				`abc,t1=val1 f1=123,f2=3.14 123`,
   255  			},
   256  
   257  			opts:    []DecoderOption{WithDecEncoding(JSON)},
   258  			ptsOpts: []Option{WithPrecision(PrecW)},
   259  		},
   260  
   261  		{
   262  			name: "decode-metric-json",
   263  			data: []byte(`[ { "measurement": "abc",  "tags": {"t1": "val1"}, "fields": {"f1": 123, "f2": 3.14, "f-str": "hello"}, "time":123} ]`),
   264  			expectLP: []string{
   265  				`abc,t1=val1 f1=123,f2=3.14 123`,
   266  			},
   267  			ptsOpts: DefaultMetricOptions(),
   268  
   269  			opts: []DecoderOption{WithDecEncoding(JSON)},
   270  		},
   271  
   272  		{
   273  			name:     "lp",
   274  			data:     []byte(`abc,tag1=v1,tag2=v2 f1=1i,f2=2 123`),
   275  			expectLP: []string{`abc,tag1=v1,tag2=v2 f1=1i,f2=2 123`},
   276  		},
   277  
   278  		{
   279  			fail: true,
   280  			name: "invalid-lp",
   281  			data: []byte(`abc,tag1=v1,tag2=v2 f1=1i,f2=2 123,`),
   282  		},
   283  
   284  		{
   285  			name: "pb",
   286  			data: func() []byte {
   287  				pt, err := NewPoint("abc",
   288  					map[string]string{"tag1": "v1", "tag2": "v2"},
   289  					map[string]interface{}{"f1": 1, "f2": 2.0},
   290  					WithTime(time.Unix(0, 123)))
   291  				assert.NoError(t, err)
   292  
   293  				enc := GetEncoder(WithEncEncoding(Protobuf))
   294  				defer PutEncoder(enc)
   295  
   296  				data, err := enc.Encode([]*Point{pt})
   297  				assert.NoError(t, err)
   298  				assert.Equal(t, 1, len(data))
   299  				return data[0]
   300  			}(),
   301  
   302  			opts:     []DecoderOption{WithDecEncoding(Protobuf)},
   303  			expectLP: []string{`abc,tag1=v1,tag2=v2 f1=1i,f2=2 123`},
   304  		},
   305  
   306  		{
   307  			fail: true,
   308  			name: "invalid-pb",
   309  			data: func() []byte {
   310  				pt, err := NewPoint("abc",
   311  					map[string]string{"tag1": "v1", "tag2": "v2"},
   312  					map[string]interface{}{"f1": 1, "f2": 2.0},
   313  					WithTime(time.Unix(0, 123)))
   314  				assert.NoError(t, err)
   315  
   316  				enc := GetEncoder(WithEncEncoding(Protobuf))
   317  				defer PutEncoder(enc)
   318  
   319  				data, err := enc.Encode([]*Point{pt})
   320  				assert.NoError(t, err)
   321  				assert.Equal(t, 1, len(data))
   322  				return data[0][:len(data[0])/2] // half of pb
   323  			}(),
   324  			opts: []DecoderOption{WithDecEncoding(Protobuf)},
   325  		},
   326  
   327  		{
   328  			name: "pb-with-fn",
   329  			data: func() []byte {
   330  				pt, err := NewPoint("abc",
   331  					map[string]string{"tag1": "v1", "tag2": "v2"},
   332  					map[string]interface{}{"f1": 1, "f2": 2.0},
   333  					WithTime(time.Unix(0, 123)))
   334  				assert.NoError(t, err)
   335  
   336  				enc := GetEncoder(WithEncEncoding(Protobuf))
   337  				defer PutEncoder(enc)
   338  
   339  				data, err := enc.Encode([]*Point{pt})
   340  				assert.NoError(t, err)
   341  				assert.Equal(t, 1, len(data))
   342  				return data[0]
   343  			}(),
   344  
   345  			fn: func(pts []*Point) error {
   346  				t.Logf("get %d point", len(pts))
   347  				fnCalled++
   348  				return nil
   349  			},
   350  
   351  			opts: []DecoderOption{WithDecEncoding(Protobuf)},
   352  
   353  			expectLP: []string{`abc,tag1=v1,tag2=v2 f1=1i,f2=2 123`},
   354  		},
   355  
   356  		{
   357  			name: "pb-with-fn-on-error",
   358  			data: func() []byte {
   359  				pt, err := NewPoint("abc",
   360  					map[string]string{"tag1": "v1", "tag2": "v2"},
   361  					map[string]interface{}{"f1": 1, "f2": 2.0},
   362  					WithTime(time.Unix(0, 123)))
   363  				assert.NoError(t, err)
   364  
   365  				enc := GetEncoder(WithEncEncoding(Protobuf))
   366  				defer PutEncoder(enc)
   367  
   368  				data, err := enc.Encode([]*Point{pt})
   369  				assert.NoError(t, err)
   370  				assert.Equal(t, 1, len(data))
   371  				return data[0]
   372  			}(),
   373  
   374  			fn: func(pts []*Point) error {
   375  				fnCalled++
   376  				return fmt.Errorf("mocked error")
   377  			},
   378  			fnErr: true,
   379  
   380  			opts:     []DecoderOption{WithDecEncoding(Protobuf)},
   381  			expectLP: []string{`abc,tag1=v1,tag2=v2 f1=1i,f2=2 123`},
   382  		},
   383  	}
   384  
   385  	for _, tc := range cases {
   386  		t.Run(tc.name, func(t *T.T) {
   387  			fnCalled = 0 // reset
   388  
   389  			opts := []DecoderOption{WithDecFn(tc.fn)}
   390  			opts = append(opts, tc.opts...)
   391  
   392  			dec := GetDecoder(opts...)
   393  			defer PutDecoder(dec)
   394  
   395  			pts, err := dec.Decode(tc.data, tc.ptsOpts...)
   396  			if tc.fail {
   397  				assert.Error(t, err, "decode %s got pts: %+#v", tc.data, pts)
   398  				t.Logf("expect error: %s", err)
   399  				return
   400  			}
   401  
   402  			if tc.fnErr {
   403  				assert.Error(t, err)
   404  			} else {
   405  				assert.NoError(t, err)
   406  			}
   407  
   408  			assert.Equal(t, len(tc.expectLP), len(pts))
   409  			for idx := range pts {
   410  				assert.Equal(t, tc.expectLP[idx], pts[idx].LineProto())
   411  
   412  				t.Logf("point: %s", pts[idx].Pretty())
   413  			}
   414  
   415  			if tc.fn != nil {
   416  				assert.Equal(t, 1, fnCalled)
   417  			}
   418  		})
   419  	}
   420  
   421  	t.Run("decode-pb-json", func(t *T.T) {
   422  		j := `[
   423  {"name":"abc","fields":[{"key":"f1","i":"123"},{"key":"f2","b":false},{"key":"t1","s":"tv1","is_tag":true},{"key":"t2","s":"tv2","is_tag":true}],"time":"123"}
   424  ]`
   425  		dec := GetDecoder(WithDecEncoding(JSON))
   426  		defer PutDecoder(dec)
   427  		pts, err := dec.Decode([]byte(j), DefaultLoggingOptions()...)
   428  		require.NoError(t, err)
   429  
   430  		for _, pt := range pts {
   431  			assert.Equal(t, "unknown", pt.Get("status").(string))
   432  
   433  			t.Logf("pt: %s", pt.Pretty())
   434  		}
   435  	})
   436  
   437  	t.Run("decode-bytes-array", func(t *T.T) {
   438  		var kvs KVs
   439  		kvs = kvs.Add("f_d_arr", MustNewAnyArray([]byte("hello"), []byte("world")), false, false)
   440  		pt := NewPointV2("m1", kvs)
   441  		enc := GetEncoder(WithEncEncoding(LineProtocol))
   442  		defer PutEncoder(enc)
   443  		arr, err := enc.Encode([]*Point{pt})
   444  		assert.NoError(t, err)
   445  
   446  		t.Logf("lp: %s", arr[0])
   447  
   448  		dec := GetDecoder(WithDecEncoding(LineProtocol))
   449  		defer PutDecoder(dec)
   450  		pts, err := dec.Decode(arr[0])
   451  		assert.NoError(t, err)
   452  		for _, pt := range pts {
   453  			t.Logf("pt: %s", pt.Pretty())
   454  		}
   455  	})
   456  
   457  	t.Run("decode-with-check", func(t *T.T) {
   458  		var kvs KVs
   459  		kvs = kvs.AddV2("f.1", 1.23, false) // f.1 rename to f_1 and key conflict
   460  		kvs = kvs.AddV2("f_1", 321, false)
   461  		kvs = kvs.AddV2("tag.1", "some-val", false, WithKVTagSet(true))
   462  
   463  		pt := NewPointV2("m1", kvs, WithTime(time.Unix(0, 123)))
   464  
   465  		enc := GetEncoder(WithEncEncoding(Protobuf))
   466  		defer PutEncoder(enc)
   467  		enc.EncodeV2([]*Point{pt})
   468  
   469  		src := make([]byte, 1<<20)
   470  		src, ok := enc.Next(src)
   471  		assert.True(t, ok)
   472  
   473  		dec := GetDecoder(WithDecEncoding(Protobuf))
   474  
   475  		pts, err := dec.Decode(src, WithDotInKey(false)) // disable dot(.) in key
   476  		assert.NoError(t, err)
   477  		assert.Len(t, pts, 1)
   478  
   479  		assert.Equal(t, int64(321), pts[0].Get("f_1").(int64))
   480  		assert.Equal(t, "some-val", pts[0].Get("tag_1").(string))
   481  
   482  		assert.Len(t, pts[0].pt.Warns, 3)
   483  
   484  		t.Logf("pt: %s", pts[0].Pretty())
   485  		t.Logf("pt: %s", pts[0].LineProto())
   486  		defer PutDecoder(dec)
   487  
   488  		// test on easyproto
   489  		dec = GetDecoder(WithDecEncoding(Protobuf), WithDecEasyproto(true))
   490  		pts, err = dec.Decode(src, WithDotInKey(false)) // disable dot(.) in key
   491  		assert.NoError(t, err)
   492  		assert.Len(t, pts, 1)
   493  
   494  		assert.Equal(t, int64(321), pts[0].Get("f_1").(int64))
   495  		assert.Equal(t, "some-val", pts[0].Get("tag_1").(string))
   496  
   497  		assert.Len(t, pts[0].pt.Warns, 3)
   498  
   499  		t.Logf("pt: %s", pts[0].Pretty())
   500  		t.Logf("pt: %s", pts[0].LineProto())
   501  		defer PutDecoder(dec)
   502  	})
   503  }
   504  
   505  func BenchmarkDecode(b *T.B) {
   506  	r := NewRander(WithFixedTags(true), WithRandText(3))
   507  	pts := r.Rand(1000)
   508  
   509  	b.Run("decode-lp", func(b *T.B) {
   510  		enc := GetEncoder()
   511  		defer PutEncoder(enc)
   512  
   513  		data, _ := enc.Encode(pts)
   514  
   515  		d := GetDecoder(WithDecEncoding(LineProtocol))
   516  		defer PutDecoder(d)
   517  
   518  		b.ResetTimer()
   519  		for i := 0; i < b.N; i++ {
   520  			d.Decode(data[0])
   521  		}
   522  	})
   523  
   524  	b.Run("decode-pb", func(b *T.B) {
   525  		enc := GetEncoder(WithEncEncoding(Protobuf))
   526  		defer PutEncoder(enc)
   527  
   528  		data, _ := enc.Encode(pts)
   529  
   530  		d := GetDecoder(WithDecEncoding(Protobuf))
   531  		defer PutDecoder(d)
   532  
   533  		b.ResetTimer()
   534  		for i := 0; i < b.N; i++ {
   535  			d.Decode(data[0])
   536  		}
   537  	})
   538  
   539  	b.Run("decode-pb-no-check", func(b *T.B) {
   540  		enc := GetEncoder(WithEncEncoding(Protobuf))
   541  		defer PutEncoder(enc)
   542  
   543  		data, _ := enc.Encode(pts)
   544  
   545  		d := GetDecoder(WithDecEncoding(Protobuf))
   546  		defer PutDecoder(d)
   547  
   548  		b.ResetTimer()
   549  		for i := 0; i < b.N; i++ {
   550  			d.Decode(data[0], WithPrecheck(false))
   551  		}
   552  	})
   553  
   554  	b.Run("decode-pb-with-easyproto", func(b *T.B) {
   555  		enc := GetEncoder(WithEncEncoding(Protobuf))
   556  		defer PutEncoder(enc)
   557  
   558  		data, _ := enc.Encode(pts)
   559  
   560  		d := GetDecoder(WithDecEncoding(Protobuf), WithDecEasyproto(true))
   561  		defer PutDecoder(d)
   562  
   563  		b.ResetTimer()
   564  		for i := 0; i < b.N; i++ {
   565  			d.Decode(data[0])
   566  		}
   567  	})
   568  
   569  	b.Run("decode-pb-with-easyproto-no-check", func(b *T.B) {
   570  		enc := GetEncoder(WithEncEncoding(Protobuf))
   571  		defer PutEncoder(enc)
   572  
   573  		data, _ := enc.Encode(pts)
   574  
   575  		d := GetDecoder(WithDecEncoding(Protobuf), WithDecEasyproto(true))
   576  		defer PutDecoder(d)
   577  
   578  		b.ResetTimer()
   579  		for i := 0; i < b.N; i++ {
   580  			d.Decode(data[0], WithPrecheck(false))
   581  		}
   582  	})
   583  
   584  	b.Run("decode-json", func(b *T.B) {
   585  		enc := GetEncoder(WithEncEncoding(JSON))
   586  		defer PutEncoder(enc)
   587  
   588  		data, _ := enc.Encode(pts)
   589  
   590  		d := GetDecoder(WithDecEncoding(JSON))
   591  		defer PutDecoder(d)
   592  
   593  		b.ResetTimer()
   594  		for i := 0; i < b.N; i++ {
   595  			d.Decode(data[0])
   596  		}
   597  	})
   598  
   599  	b.Run("decode-json-no-check", func(b *T.B) {
   600  		enc := GetEncoder(WithEncEncoding(JSON))
   601  		defer PutEncoder(enc)
   602  
   603  		data, _ := enc.Encode(pts)
   604  
   605  		d := GetDecoder(WithDecEncoding(JSON))
   606  		defer PutDecoder(d)
   607  
   608  		b.ResetTimer()
   609  		for i := 0; i < b.N; i++ {
   610  			d.Decode(data[0], WithPrecheck(false))
   611  		}
   612  	})
   613  
   614  	b.Run("decode-pbjson-no-check", func(b *T.B) {
   615  		enc := GetEncoder(WithEncEncoding(JSON))
   616  		defer PutEncoder(enc)
   617  
   618  		for _, pt := range pts {
   619  			pt.SetFlag(Ppb)
   620  		}
   621  
   622  		data, _ := enc.Encode(pts)
   623  
   624  		d := GetDecoder(WithDecEncoding(JSON))
   625  		defer PutDecoder(d)
   626  
   627  		b.ResetTimer()
   628  		for i := 0; i < b.N; i++ {
   629  			d.Decode(data[0], WithPrecheck(false))
   630  		}
   631  	})
   632  }
   633  
   634  func BenchmarkBytes2String(b *T.B) {
   635  	repeat := 1
   636  	raw := []byte("xxxxxxxxxxxxxxxx")
   637  
   638  	bytesData := bytes.Repeat(raw, repeat)
   639  	strData := strings.Repeat(string(raw), repeat)
   640  
   641  	str := string(raw)
   642  	b.Logf("str:   %p", &str)
   643  	b.Logf("bytes: %p", raw)
   644  	b.Logf("repeat: %p", &repeat)
   645  
   646  	b.Logf("str:   %p", &strData)
   647  	b.Logf("bytes: %p", []byte(strData))
   648  
   649  	{
   650  		y := string(bytesData)
   651  		_ = y
   652  		b.Errorf("y: %p, d: %p", &y, bytesData)
   653  	}
   654  
   655  	{
   656  		b.Errorf("y: %p, d: %p", []byte(strData), &strData)
   657  	}
   658  
   659  	b.Run("bytes2str", func(b *T.B) {
   660  		for i := 0; i < b.N; i++ {
   661  			y := string(raw)
   662  			_ = y
   663  		}
   664  	})
   665  
   666  	b.Run("str2bytes", func(b *T.B) {
   667  		for i := 0; i < b.N; i++ {
   668  			y := []byte(strData)
   669  			_ = y
   670  		}
   671  	})
   672  }