diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-07 14:01:44 -0700 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2023-02-10 14:09:56 -0700 |
commit | 483bbdc970b26d774ace39edfde8420aba53b742 (patch) | |
tree | ee5fcacbba4d4eb7c44e4cb1f35fb950f11aee1d /compat/json/borrowed_bench_test.go | |
parent | 480ccfd05a13ac36516c536a71203280a31b4d28 (diff) |
Sync borrowed code from Go 1.20
New tests mean encode.go and compat.go also need some bugfixes.
Diffstat (limited to 'compat/json/borrowed_bench_test.go')
-rw-r--r-- | compat/json/borrowed_bench_test.go | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/compat/json/borrowed_bench_test.go b/compat/json/borrowed_bench_test.go index 443a13d..0c13df1 100644 --- a/compat/json/borrowed_bench_test.go +++ b/compat/json/borrowed_bench_test.go @@ -19,6 +19,7 @@ import ( "io" "os" "reflect" + "regexp" "runtime" "strings" "sync" @@ -100,6 +101,36 @@ func BenchmarkCodeEncoder(b *testing.B) { b.SetBytes(int64(len(codeJSON))) } +func BenchmarkCodeEncoderError(b *testing.B) { + b.ReportAllocs() + if codeJSON == nil { + b.StopTimer() + codeInit(b) // MODIFIED: use the test logger + b.StartTimer() + } + + // Trigger an error in Marshal with cyclic data. + type Dummy struct { + Name string + Next *Dummy + } + dummy := Dummy{Name: "Dummy"} + dummy.Next = &dummy + + b.RunParallel(func(pb *testing.PB) { + enc := NewEncoder(io.Discard) + for pb.Next() { + if err := enc.Encode(&codeStruct); err != nil { + b.Fatal("Encode:", err) + } + if _, err := Marshal(dummy); err == nil { + b.Fatal("expect an error here") + } + } + }) + b.SetBytes(int64(len(codeJSON))) +} + func BenchmarkCodeMarshal(b *testing.B) { b.ReportAllocs() if codeJSON == nil { @@ -117,6 +148,35 @@ func BenchmarkCodeMarshal(b *testing.B) { b.SetBytes(int64(len(codeJSON))) } +func BenchmarkCodeMarshalError(b *testing.B) { + b.ReportAllocs() + if codeJSON == nil { + b.StopTimer() + codeInit(b) // MODIFIED: use the test logger + b.StartTimer() + } + + // Trigger an error in Marshal with cyclic data. + type Dummy struct { + Name string + Next *Dummy + } + dummy := Dummy{Name: "Dummy"} + dummy.Next = &dummy + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + if _, err := Marshal(&codeStruct); err != nil { + b.Fatal("Marshal:", err) + } + if _, err := Marshal(dummy); err == nil { + b.Fatal("expect an error here") + } + } + }) + b.SetBytes(int64(len(codeJSON))) +} + func benchMarshalBytes(n int) func(*testing.B) { sample := []byte("hello world") // Use a struct pointer, to avoid an allocation when passing it as an @@ -135,6 +195,36 @@ func benchMarshalBytes(n int) func(*testing.B) { } } +func benchMarshalBytesError(n int) func(*testing.B) { + sample := []byte("hello world") + // Use a struct pointer, to avoid an allocation when passing it as an + // interface parameter to Marshal. + v := &struct { + Bytes []byte + }{ + bytes.Repeat(sample, (n/len(sample))+1)[:n], + } + + // Trigger an error in Marshal with cyclic data. + type Dummy struct { + Name string + Next *Dummy + } + dummy := Dummy{Name: "Dummy"} + dummy.Next = &dummy + + return func(b *testing.B) { + for i := 0; i < b.N; i++ { + if _, err := Marshal(v); err != nil { + b.Fatal("Marshal:", err) + } + if _, err := Marshal(dummy); err == nil { + b.Fatal("expect an error here") + } + } + } +} + func BenchmarkMarshalBytes(b *testing.B) { b.ReportAllocs() // 32 fits within encodeState.scratch. @@ -146,6 +236,17 @@ func BenchmarkMarshalBytes(b *testing.B) { b.Run("4096", benchMarshalBytes(4096)) } +func BenchmarkMarshalBytesError(b *testing.B) { + b.ReportAllocs() + // 32 fits within encodeState.scratch. + b.Run("32", benchMarshalBytesError(32)) + // 256 doesn't fit in encodeState.scratch, but is small enough to + // allocate and avoid the slower base64.NewEncoder. + b.Run("256", benchMarshalBytesError(256)) + // 4096 is large enough that we want to avoid allocating for it. + b.Run("4096", benchMarshalBytesError(4096)) +} + func BenchmarkCodeDecoder(b *testing.B) { b.ReportAllocs() if codeJSON == nil { @@ -411,3 +512,33 @@ func BenchmarkEncodeMarshaler(b *testing.B) { } }) } + +func BenchmarkEncoderEncode(b *testing.B) { + b.ReportAllocs() + type T struct { + X, Y string + } + v := &T{"foo", "bar"} + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + if err := NewEncoder(io.Discard).Encode(v); err != nil { + b.Fatal(err) + } + } + }) +} + +func BenchmarkNumberIsValid(b *testing.B) { + s := "-61657.61667E+61673" + for i := 0; i < b.N; i++ { + isValidNumber(s) + } +} + +func BenchmarkNumberIsValidRegexp(b *testing.B) { + var jsonNumberRegexp = regexp.MustCompile(`^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$`) + s := "-61657.61667E+61673" + for i := 0; i < b.N; i++ { + jsonNumberRegexp.MatchString(s) + } +} |