Skip to content

Commit

Permalink
Merge pull request #19 from liggitt/go123
Browse files Browse the repository at this point in the history
Sync with go1.23
  • Loading branch information
k8s-ci-robot authored Oct 8, 2024
2 parents bc3834c + e32a7b5 commit c46165d
Show file tree
Hide file tree
Showing 18 changed files with 2,175 additions and 2,195 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ vet:
go vet sigs.k8s.io/json

@echo "checking for external dependencies"
@deps=$$(go mod graph); \
@deps=$$(go list -f '{{ if not (or .Standard .Module.Main) }}{{.ImportPath}}{{ end }}' -deps sigs.k8s.io/json/... || true); \
if [ -n "$${deps}" ]; then \
echo "only stdlib dependencies allowed, found:"; \
echo "$${deps}"; \
Expand Down
2 changes: 1 addition & 1 deletion OWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

approvers:
- deads2k
- lavalamp
- jpbetz
- liggitt
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module sigs.k8s.io/json

go 1.18
go 1.21
210 changes: 192 additions & 18 deletions internal/golang/encoding/json/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"io"
"os"
"reflect"
"regexp"
"runtime"
"strings"
"sync"
Expand Down Expand Up @@ -91,7 +92,37 @@ func BenchmarkCodeEncoder(b *testing.B) {
enc := NewEncoder(io.Discard)
for pb.Next() {
if err := enc.Encode(&codeStruct); err != nil {
b.Fatal("Encode:", err)
b.Fatalf("Encode error: %v", err)
}
}
})
b.SetBytes(int64(len(codeJSON)))
}

func BenchmarkCodeEncoderError(b *testing.B) {
b.ReportAllocs()
if codeJSON == nil {
b.StopTimer()
codeInit()
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.Fatalf("Encode error: %v", err)
}
if _, err := Marshal(dummy); err == nil {
b.Fatal("Marshal error: got nil, want non-nil")
}
}
})
Expand All @@ -108,7 +139,36 @@ func BenchmarkCodeMarshal(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if _, err := Marshal(&codeStruct); err != nil {
b.Fatal("Marshal:", err)
b.Fatalf("Marshal error: %v", err)
}
}
})
b.SetBytes(int64(len(codeJSON)))
}

func BenchmarkCodeMarshalError(b *testing.B) {
b.ReportAllocs()
if codeJSON == nil {
b.StopTimer()
codeInit()
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.Fatalf("Marshal error: %v", err)
}
if _, err := Marshal(dummy); err == nil {
b.Fatal("Marshal error: got nil, want non-nil")
}
}
})
Expand All @@ -127,7 +187,37 @@ func benchMarshalBytes(n int) func(*testing.B) {
return func(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, err := Marshal(v); err != nil {
b.Fatal("Marshal:", err)
b.Fatalf("Marshal error: %v", err)
}
}
}
}

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.Fatalf("Marshal error: %v", err)
}
if _, err := Marshal(dummy); err == nil {
b.Fatal("Marshal error: got nil, want non-nil")
}
}
}
Expand All @@ -144,6 +234,33 @@ 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 BenchmarkMarshalMap(b *testing.B) {
b.ReportAllocs()
m := map[string]int{
"key3": 3,
"key2": 2,
"key1": 1,
}
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if _, err := Marshal(m); err != nil {
b.Fatal("Marshal:", err)
}
}
})
}

func BenchmarkCodeDecoder(b *testing.B) {
b.ReportAllocs()
if codeJSON == nil {
Expand All @@ -162,7 +279,7 @@ func BenchmarkCodeDecoder(b *testing.B) {
buf.WriteByte('\n')
buf.WriteByte('\n')
if err := dec.Decode(&r); err != nil {
b.Fatal("Decode:", err)
b.Fatalf("Decode error: %v", err)
}
}
})
Expand All @@ -179,7 +296,7 @@ func BenchmarkUnicodeDecoder(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
if err := dec.Decode(&out); err != nil {
b.Fatal("Decode:", err)
b.Fatalf("Decode error: %v", err)
}
r.Seek(0, 0)
}
Expand All @@ -193,7 +310,7 @@ func BenchmarkDecoderStream(b *testing.B) {
buf.WriteString(`"` + strings.Repeat("x", 1000000) + `"` + "\n\n\n")
var x any
if err := dec.Decode(&x); err != nil {
b.Fatal("Decode:", err)
b.Fatalf("Decode error: %v", err)
}
ones := strings.Repeat(" 1\n", 300000) + "\n\n\n"
b.StartTimer()
Expand All @@ -202,8 +319,11 @@ func BenchmarkDecoderStream(b *testing.B) {
buf.WriteString(ones)
}
x = nil
if err := dec.Decode(&x); err != nil || x != 1.0 {
b.Fatalf("Decode: %v after %d", err, i)
switch err := dec.Decode(&x); {
case err != nil:
b.Fatalf("Decode error: %v", err)
case x != 1.0:
b.Fatalf("Decode: got %v want 1.0", i)
}
}
}
Expand All @@ -219,7 +339,7 @@ func BenchmarkCodeUnmarshal(b *testing.B) {
for pb.Next() {
var r codeResponse
if err := Unmarshal(codeJSON, &r); err != nil {
b.Fatal("Unmarshal:", err)
b.Fatalf("Unmarshal error: %v", err)
}
}
})
Expand All @@ -237,7 +357,7 @@ func BenchmarkCodeUnmarshalReuse(b *testing.B) {
var r codeResponse
for pb.Next() {
if err := Unmarshal(codeJSON, &r); err != nil {
b.Fatal("Unmarshal:", err)
b.Fatalf("Unmarshal error: %v", err)
}
}
})
Expand All @@ -251,7 +371,7 @@ func BenchmarkUnmarshalString(b *testing.B) {
var s string
for pb.Next() {
if err := Unmarshal(data, &s); err != nil {
b.Fatal("Unmarshal:", err)
b.Fatalf("Unmarshal error: %v", err)
}
}
})
Expand All @@ -264,7 +384,7 @@ func BenchmarkUnmarshalFloat64(b *testing.B) {
var f float64
for pb.Next() {
if err := Unmarshal(data, &f); err != nil {
b.Fatal("Unmarshal:", err)
b.Fatalf("Unmarshal error: %v", err)
}
}
})
Expand All @@ -277,7 +397,20 @@ func BenchmarkUnmarshalInt64(b *testing.B) {
var x int64
for pb.Next() {
if err := Unmarshal(data, &x); err != nil {
b.Fatal("Unmarshal:", err)
b.Fatalf("Unmarshal error: %v", err)
}
}
})
}

func BenchmarkUnmarshalMap(b *testing.B) {
b.ReportAllocs()
data := []byte(`{"key1":"value1","key2":"value2","key3":"value3"}`)
b.RunParallel(func(pb *testing.PB) {
x := make(map[string]string, 3)
for pb.Next() {
if err := Unmarshal(data, &x); err != nil {
b.Fatalf("Unmarshal error: %v", err)
}
}
})
Expand All @@ -290,7 +423,7 @@ func BenchmarkIssue10335(b *testing.B) {
var s struct{}
for pb.Next() {
if err := Unmarshal(j, &s); err != nil {
b.Fatal(err)
b.Fatalf("Unmarshal error: %v", err)
}
}
})
Expand All @@ -306,7 +439,7 @@ func BenchmarkIssue34127(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
if _, err := Marshal(&j); err != nil {
b.Fatal(err)
b.Fatalf("Marshal error: %v", err)
}
}
})
Expand All @@ -319,7 +452,7 @@ func BenchmarkUnmapped(b *testing.B) {
var s struct{}
for pb.Next() {
if err := Unmarshal(j, &s); err != nil {
b.Fatal(err)
b.Fatalf("Unmarshal error: %v", err)
}
}
})
Expand All @@ -333,7 +466,7 @@ func BenchmarkTypeFieldsCache(b *testing.B) {
// Dynamically generate many new types.
types := make([]reflect.Type, maxTypes)
fs := []reflect.StructField{{
Type: reflect.TypeOf(""),
Type: reflect.TypeFor[string](),
Index: []int{0},
}}
for i := range types {
Expand Down Expand Up @@ -400,8 +533,49 @@ func BenchmarkEncodeMarshaler(b *testing.B) {

for pb.Next() {
if err := enc.Encode(&m); err != nil {
b.Fatal("Encode:", err)
b.Fatalf("Encode error: %v", err)
}
}
})
}

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.Fatalf("Encode error: %v", 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)
}
}

func BenchmarkUnmarshalNumber(b *testing.B) {
b.ReportAllocs()
data := []byte(`"-61657.61667E+61673"`)
var number Number
for i := 0; i < b.N; i++ {
if err := Unmarshal(data, &number); err != nil {
b.Fatal("Unmarshal:", err)
}
}
}
Loading

0 comments on commit c46165d

Please sign in to comment.