Correct benchmarks for unstructured, show json-iter

The unstructured benchmarks incorrectly charged setup of objects to the benchmark.

Split each, and add comparison to json iter.

```
BenchmarkToUnstructured-12                 	   30000	     49716 ns/op	   15358 B/op	     221 allocs/op
BenchmarkFromUnstructured-12               	   30000	     53585 ns/op	    7773 B/op	     185 allocs/op
BenchmarkToUnstructuredViaJSON-12          	   30000	     53716 ns/op	   22609 B/op	     323 allocs/op
BenchmarkFromUnstructuredViaJSON-12        	   10000	    121007 ns/op	   29601 B/op	     438 allocs/op
BenchmarkToUnstructuredViaJSONIter/compat-12         	   30000	     57796 ns/op	   27685 B/op	     431 allocs/op
BenchmarkToUnstructuredViaJSONIter/default-12        	   30000	     51114 ns/op	   20377 B/op	     415 allocs/op
BenchmarkToUnstructuredViaJSONIter/fastest-12        	   30000	     48521 ns/op	   20103 B/op	     405 allocs/op
BenchmarkFromUnstructuredViaJSONIter/compat-12       	   20000	     83389 ns/op	   48777 B/op	     591 allocs/op
BenchmarkFromUnstructuredViaJSONIter/default-12      	   30000	     42717 ns/op	   13439 B/op	     291 allocs/op
BenchmarkFromUnstructuredViaJSONIter/fastest-12      	   50000	     35102 ns/op	   12070 B/op	     203 allocs/op
```
This commit is contained in:
Clayton Coleman
2019-01-27 14:41:36 -05:00
parent 08d0522730
commit d0daa1082f

View File

@@ -19,11 +19,13 @@ package testing
import (
"math/rand"
"reflect"
"sort"
"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"
apiequality "k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/meta"
@@ -99,7 +101,7 @@ func doRoundTrip(t *testing.T, internalVersion schema.GroupVersion, externalVers
return
}
newUnstr, err := runtime.NewTestUnstructuredConverter(apiequality.Semantic).ToUnstructured(item)
newUnstr, err := runtime.DefaultUnstructuredConverter.ToUnstructured(item)
if err != nil {
t.Errorf("ToUnstructured failed: %v", err)
return
@@ -163,7 +165,7 @@ func TestRoundTripWithEmptyCreationTimestamp(t *testing.T) {
// attempt to re-convert unstructured object - conversion should not fail
// based on empty metadata fields, such as creationTimestamp
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 {
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)
size := len(items)
convertor := runtime.DefaultUnstructuredConverter
b.ResetTimer()
for i := 0; i < b.N; i++ {
unstr, err := runtime.NewTestUnstructuredConverter(apiequality.Semantic).ToUnstructured(&items[i%size])
if err != nil {
b.Fatalf("unexpected error: %v", err)
}
obj := v1.Pod{}
if err := runtime.NewTestUnstructuredConverter(apiequality.Semantic).FromUnstructured(unstr, &obj); err != nil {
unstr, err := convertor.ToUnstructured(&items[i%size])
if err != nil || unstr == nil {
b.Fatalf("unexpected error: %v", err)
}
}
b.StopTimer()
}
func BenchmarkToFromUnstructuredViaJSON(b *testing.B) {
func BenchmarkFromUnstructured(b *testing.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)
b.ResetTimer()
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{}
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.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()
})
}
}