mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #73973 from smarterclayton/fix_benchmark
Fix the unstructured conversion benchmarks to be correct
This commit is contained in:
		@@ -19,11 +19,13 @@ package testing
 | 
				
			|||||||
import (
 | 
					import (
 | 
				
			||||||
	"math/rand"
 | 
						"math/rand"
 | 
				
			||||||
	"reflect"
 | 
						"reflect"
 | 
				
			||||||
 | 
						"sort"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/google/gofuzz"
 | 
						fuzz "github.com/google/gofuzz"
 | 
				
			||||||
 | 
						jsoniter "github.com/json-iterator/go"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"k8s.io/api/core/v1"
 | 
						v1 "k8s.io/api/core/v1"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
 | 
						"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
 | 
				
			||||||
	apiequality "k8s.io/apimachinery/pkg/api/equality"
 | 
						apiequality "k8s.io/apimachinery/pkg/api/equality"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/api/meta"
 | 
						"k8s.io/apimachinery/pkg/api/meta"
 | 
				
			||||||
@@ -99,7 +101,7 @@ func doRoundTrip(t *testing.T, internalVersion schema.GroupVersion, externalVers
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	newUnstr, err := runtime.NewTestUnstructuredConverter(apiequality.Semantic).ToUnstructured(item)
 | 
						newUnstr, err := runtime.DefaultUnstructuredConverter.ToUnstructured(item)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("ToUnstructured failed: %v", err)
 | 
							t.Errorf("ToUnstructured failed: %v", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@@ -163,7 +165,7 @@ func TestRoundTripWithEmptyCreationTimestamp(t *testing.T) {
 | 
				
			|||||||
			// attempt to re-convert unstructured object - conversion should not fail
 | 
								// attempt to re-convert unstructured object - conversion should not fail
 | 
				
			||||||
			// based on empty metadata fields, such as creationTimestamp
 | 
								// based on empty metadata fields, such as creationTimestamp
 | 
				
			||||||
			newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object)
 | 
								newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object)
 | 
				
			||||||
			err = runtime.NewTestUnstructuredConverter(apiequality.Semantic).FromUnstructured(unstructObj.Object, newObj)
 | 
								err = runtime.DefaultUnstructuredConverter.FromUnstructured(unstructObj.Object, newObj)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				t.Fatalf("FromUnstructured failed: %v", err)
 | 
									t.Fatalf("FromUnstructured failed: %v", err)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -171,44 +173,160 @@ func TestRoundTripWithEmptyCreationTimestamp(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func BenchmarkToFromUnstructured(b *testing.B) {
 | 
					func BenchmarkToUnstructured(b *testing.B) {
 | 
				
			||||||
	items := benchmarkItems(b)
 | 
						items := benchmarkItems(b)
 | 
				
			||||||
	size := len(items)
 | 
						size := len(items)
 | 
				
			||||||
 | 
						convertor := runtime.DefaultUnstructuredConverter
 | 
				
			||||||
	b.ResetTimer()
 | 
						b.ResetTimer()
 | 
				
			||||||
	for i := 0; i < b.N; i++ {
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
		unstr, err := runtime.NewTestUnstructuredConverter(apiequality.Semantic).ToUnstructured(&items[i%size])
 | 
							unstr, err := convertor.ToUnstructured(&items[i%size])
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil || unstr == nil {
 | 
				
			||||||
			b.Fatalf("unexpected error: %v", err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		obj := v1.Pod{}
 | 
					 | 
				
			||||||
		if err := runtime.NewTestUnstructuredConverter(apiequality.Semantic).FromUnstructured(unstr, &obj); err != nil {
 | 
					 | 
				
			||||||
			b.Fatalf("unexpected error: %v", err)
 | 
								b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	b.StopTimer()
 | 
						b.StopTimer()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func BenchmarkToFromUnstructuredViaJSON(b *testing.B) {
 | 
					func BenchmarkFromUnstructured(b *testing.B) {
 | 
				
			||||||
	items := benchmarkItems(b)
 | 
						items := benchmarkItems(b)
 | 
				
			||||||
 | 
						convertor := runtime.DefaultUnstructuredConverter
 | 
				
			||||||
 | 
						var unstr []map[string]interface{}
 | 
				
			||||||
 | 
						for i := range items {
 | 
				
			||||||
 | 
							item, err := convertor.ToUnstructured(&items[i])
 | 
				
			||||||
 | 
							if err != nil || item == nil {
 | 
				
			||||||
 | 
								b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							unstr = append(unstr, item)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	size := len(items)
 | 
						size := len(items)
 | 
				
			||||||
	b.ResetTimer()
 | 
						b.ResetTimer()
 | 
				
			||||||
	for i := 0; i < b.N; i++ {
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
		data, err := json.Marshal(&items[i%size])
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			b.Fatalf("unexpected error: %v", err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		unstr := map[string]interface{}{}
 | 
					 | 
				
			||||||
		if err := json.Unmarshal(data, &unstr); err != nil {
 | 
					 | 
				
			||||||
			b.Fatalf("unexpected error: %v", err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		data, err = json.Marshal(unstr)
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			b.Fatalf("unexpected error: %v", err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		obj := v1.Pod{}
 | 
							obj := v1.Pod{}
 | 
				
			||||||
		if err := json.Unmarshal(data, &obj); err != nil {
 | 
							if err := convertor.FromUnstructured(unstr[i%size], &obj); err != nil {
 | 
				
			||||||
			b.Fatalf("unexpected error: %v", err)
 | 
								b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	b.StopTimer()
 | 
						b.StopTimer()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func BenchmarkToUnstructuredViaJSON(b *testing.B) {
 | 
				
			||||||
 | 
						items := benchmarkItems(b)
 | 
				
			||||||
 | 
						var data [][]byte
 | 
				
			||||||
 | 
						for i := range items {
 | 
				
			||||||
 | 
							item, err := json.Marshal(&items[i])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							data = append(data, item)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						size := len(items)
 | 
				
			||||||
 | 
						b.ResetTimer()
 | 
				
			||||||
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
 | 
							unstr := map[string]interface{}{}
 | 
				
			||||||
 | 
							if err := json.Unmarshal(data[i%size], &unstr); err != nil {
 | 
				
			||||||
 | 
								b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						b.StopTimer()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func BenchmarkFromUnstructuredViaJSON(b *testing.B) {
 | 
				
			||||||
 | 
						items := benchmarkItems(b)
 | 
				
			||||||
 | 
						var unstr []map[string]interface{}
 | 
				
			||||||
 | 
						for i := range items {
 | 
				
			||||||
 | 
							data, err := json.Marshal(&items[i])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							item := map[string]interface{}{}
 | 
				
			||||||
 | 
							if err := json.Unmarshal(data, &item); err != nil {
 | 
				
			||||||
 | 
								b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							unstr = append(unstr, item)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						size := len(items)
 | 
				
			||||||
 | 
						b.ResetTimer()
 | 
				
			||||||
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
 | 
							item, err := json.Marshal(unstr[i%size])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							obj := v1.Pod{}
 | 
				
			||||||
 | 
							if err := json.Unmarshal(item, &obj); err != nil {
 | 
				
			||||||
 | 
								b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						b.StopTimer()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func BenchmarkToUnstructuredViaJSONIter(b *testing.B) {
 | 
				
			||||||
 | 
						items := benchmarkItems(b)
 | 
				
			||||||
 | 
						size := len(items)
 | 
				
			||||||
 | 
						var keys []string
 | 
				
			||||||
 | 
						for k := range jsonIterConfig {
 | 
				
			||||||
 | 
							keys = append(keys, k)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sort.Strings(keys)
 | 
				
			||||||
 | 
						for _, name := range keys {
 | 
				
			||||||
 | 
							c := jsonIterConfig[name]
 | 
				
			||||||
 | 
							b.Run(name, func(b *testing.B) {
 | 
				
			||||||
 | 
								b.ResetTimer()
 | 
				
			||||||
 | 
								for i := 0; i < b.N; i++ {
 | 
				
			||||||
 | 
									data, err := c.Marshal(&items[i%size])
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									unstr := map[string]interface{}{}
 | 
				
			||||||
 | 
									if err := c.Unmarshal(data, &unstr); err != nil {
 | 
				
			||||||
 | 
										b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								b.StopTimer()
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var jsonIterConfig = map[string]jsoniter.API{
 | 
				
			||||||
 | 
						"default": jsoniter.ConfigDefault,
 | 
				
			||||||
 | 
						"fastest": jsoniter.ConfigFastest,
 | 
				
			||||||
 | 
						"compat":  jsoniter.ConfigCompatibleWithStandardLibrary,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func BenchmarkFromUnstructuredViaJSONIter(b *testing.B) {
 | 
				
			||||||
 | 
						items := benchmarkItems(b)
 | 
				
			||||||
 | 
						var unstr []map[string]interface{}
 | 
				
			||||||
 | 
						for i := range items {
 | 
				
			||||||
 | 
							data, err := jsoniter.Marshal(&items[i])
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							item := map[string]interface{}{}
 | 
				
			||||||
 | 
							if err := json.Unmarshal(data, &item); err != nil {
 | 
				
			||||||
 | 
								b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							unstr = append(unstr, item)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						size := len(items)
 | 
				
			||||||
 | 
						var keys []string
 | 
				
			||||||
 | 
						for k := range jsonIterConfig {
 | 
				
			||||||
 | 
							keys = append(keys, k)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sort.Strings(keys)
 | 
				
			||||||
 | 
						for _, name := range keys {
 | 
				
			||||||
 | 
							c := jsonIterConfig[name]
 | 
				
			||||||
 | 
							b.Run(name, func(b *testing.B) {
 | 
				
			||||||
 | 
								b.ResetTimer()
 | 
				
			||||||
 | 
								for i := 0; i < b.N; i++ {
 | 
				
			||||||
 | 
									item, err := c.Marshal(unstr[i%size])
 | 
				
			||||||
 | 
									if err != nil {
 | 
				
			||||||
 | 
										b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									obj := v1.Pod{}
 | 
				
			||||||
 | 
									if err := c.Unmarshal(item, &obj); err != nil {
 | 
				
			||||||
 | 
										b.Fatalf("unexpected error: %v", err)
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								b.StopTimer()
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -746,7 +746,7 @@ func isZero(v reflect.Value) bool {
 | 
				
			|||||||
func structToUnstructured(sv, dv reflect.Value) error {
 | 
					func structToUnstructured(sv, dv reflect.Value) error {
 | 
				
			||||||
	st, dt := sv.Type(), dv.Type()
 | 
						st, dt := sv.Type(), dv.Type()
 | 
				
			||||||
	if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 {
 | 
						if dt.Kind() == reflect.Interface && dv.NumMethod() == 0 {
 | 
				
			||||||
		dv.Set(reflect.MakeMap(mapStringInterfaceType))
 | 
							dv.Set(reflect.MakeMapWithSize(mapStringInterfaceType, st.NumField()))
 | 
				
			||||||
		dv = dv.Elem()
 | 
							dv = dv.Elem()
 | 
				
			||||||
		dt = dv.Type()
 | 
							dt = dv.Type()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user