...

Source file src/sigs.k8s.io/yaml/bench_test.go

Documentation: sigs.k8s.io/yaml

     1  /*
     2  Copyright 2022 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package yaml
    18  
    19  import (
    20  	"encoding/json"
    21  	"fmt"
    22  	"testing"
    23  
    24  	"sigs.k8s.io/yaml/goyaml.v2"
    25  )
    26  
    27  func newBenchmarkObject() interface{} {
    28  	data := struct {
    29  		Object map[string]interface{}
    30  		Items  []interface{}
    31  	}{
    32  		Object: map[string]interface{}{
    33  			"apiVersion": "v1",
    34  			"kind":       "PodList",
    35  		},
    36  		Items: []interface{}{},
    37  	}
    38  	for i := 0; i < 1000; i++ {
    39  		item := struct {
    40  			Object map[string]interface{}
    41  		}{
    42  			Object: map[string]interface{}{
    43  				"apiVersion": "v1",
    44  				"kind":       "Pod",
    45  				"metadata": map[string]interface{}{
    46  					"creationTimestamp": "2022-04-18T21:03:19Z",
    47  					"labels": map[string]interface{}{
    48  						"run": fmt.Sprintf("pod%d", i),
    49  					},
    50  					"name":            fmt.Sprintf("pod%d", i),
    51  					"namespace":       "default",
    52  					"resourceVersion": "27622089",
    53  					"uid":             "e8fe9315-3bed-4bb6-a70a-fb697c60deda",
    54  				},
    55  				"spec": map[string]interface{}{
    56  					"containers": map[string]interface{}{
    57  						"args": []string{
    58  							"nc",
    59  							"-lk",
    60  							"-p",
    61  							"8080",
    62  							"-e",
    63  							"cat",
    64  						},
    65  						"image":                    "busybox",
    66  						"imagePullPolicy":          "Always",
    67  						"name":                     "echo",
    68  						"resources":                map[string]interface{}{},
    69  						"terminationMessagePath":   "/dev/termination-log",
    70  						"terminationMessagePolicy": "File",
    71  						"volumeMounts": map[string]interface{}{
    72  							"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
    73  							"name":      "kube-api-access-cpxzb",
    74  							"readOnly":  true,
    75  						},
    76  					},
    77  					"dnsPolicy":                     "ClusterFirst",
    78  					"enableServiceLinks":            true,
    79  					"nodeName":                      "k8s-worker-1",
    80  					"preemptionPolicy":              "PreemptLowerPriority",
    81  					"priority":                      0,
    82  					"restartPolicy":                 "Always",
    83  					"schedulerName":                 "default-scheduler",
    84  					"securityContext":               map[string]interface{}{},
    85  					"serviceAccount":                "default",
    86  					"serviceAccountName":            "default",
    87  					"terminationGracePeriodSeconds": 30,
    88  					"tolerations": []map[string]interface{}{
    89  						{
    90  							"effect":            "NoExecute",
    91  							"key":               "node.kubernetes.io/not-ready",
    92  							"operator":          "Exists",
    93  							"tolerationSeconds": 300,
    94  						},
    95  						{
    96  							"effect":            "NoExecute",
    97  							"key":               "node.kubernetes.io/unreachable",
    98  							"operator":          "Exists",
    99  							"tolerationSeconds": 300,
   100  						},
   101  					},
   102  					"volumes": []map[string]interface{}{
   103  						{
   104  							"name": "kube-api-access-cpxzb",
   105  							"projected": map[string]interface{}{
   106  								"defaultMode": 420,
   107  								"sources": []map[string]interface{}{
   108  									{
   109  										"serviceAccountToken": map[string]interface{}{
   110  											"expirationSeconds": 3607,
   111  											"path":              "token",
   112  										},
   113  									},
   114  									{
   115  										"configMap": map[string]interface{}{
   116  											"items": []map[string]interface{}{
   117  												{
   118  													"key":  "ca.crt",
   119  													"path": "ca.crt",
   120  												},
   121  											},
   122  											"name": "kube-root-ca.crt",
   123  										},
   124  									},
   125  									{
   126  										"downwardAPI": map[string]interface{}{
   127  											"items": []map[string]interface{}{
   128  												{
   129  													"fieldRef": map[string]interface{}{
   130  														"apiVersion": "v1",
   131  														"fieldPath":  "metadata.namespace",
   132  													},
   133  													"path": "namespace",
   134  												},
   135  											},
   136  										},
   137  									},
   138  								},
   139  							},
   140  						},
   141  					},
   142  					"status": map[string]interface{}{
   143  						"conditions": []map[string]interface{}{
   144  							{
   145  								"lastProbeTime":      nil,
   146  								"lastTransitionTime": "2022-04-18T21:03:19Z",
   147  								"status":             "True",
   148  								"type":               "Initialized",
   149  							},
   150  							{
   151  								"lastProbeTime":      nil,
   152  								"lastTransitionTime": "2022-04-18T21:03:20Z",
   153  								"status":             "True",
   154  								"type":               "Ready",
   155  							},
   156  							{
   157  								"lastProbeTime":      nil,
   158  								"lastTransitionTime": "2022-04-18T21:03:20Z",
   159  								"status":             "True",
   160  								"type":               "ContainersReady",
   161  							},
   162  							{
   163  								"lastProbeTime":      nil,
   164  								"lastTransitionTime": "2022-04-18T21:03:19Z",
   165  								"status":             "True",
   166  								"type":               "PodScheduled",
   167  							},
   168  						},
   169  						"containerStatuses": []map[string]interface{}{
   170  							{
   171  								"containerID":  "containerd://ed8afc051a21749e911a4dd4671e520dc81c8e1424853b6254872a3f461bb157",
   172  								"image":        "docker.io/library/busybox:latest",
   173  								"imageID":      "docker.io/library/busybox@sha256:d2b53584f580310186df7a2055ce3ff83cc0df6caacf1e3489bff8cf5d0af5d8",
   174  								"lastState":    map[string]interface{}{},
   175  								"name":         "echo",
   176  								"ready":        true,
   177  								"restartCount": 0,
   178  								"started":      true,
   179  								"state": map[string]interface{}{
   180  									"running": map[string]interface{}{
   181  										"startedAt": "2022-04-18T21:03:20Z",
   182  									},
   183  								},
   184  							},
   185  						},
   186  						"hostIP": "192.168.200.12",
   187  						"phase":  "Running",
   188  						"podIP":  "10.244.1.248",
   189  						"podIPs": []map[string]interface{}{
   190  							{
   191  								"ip": "10.244.1.248",
   192  							},
   193  						},
   194  						"qosClass":  "BestEffort",
   195  						"startTime": "2022-04-18T21:03:19Z",
   196  					},
   197  				},
   198  			},
   199  		}
   200  		data.Items = append(data.Items, item)
   201  	}
   202  	return data
   203  }
   204  
   205  func newBenchmarkYAML() ([]byte, error) {
   206  	return yaml.Marshal(newBenchmarkObject())
   207  }
   208  
   209  func BenchmarkMarshal(b *testing.B) {
   210  	// Setup
   211  	obj := newBenchmarkObject()
   212  
   213  	// Record the number of bytes per operation
   214  	result, err := Marshal(obj)
   215  	if err != nil {
   216  		b.Errorf("error marshaling YAML: %v", err)
   217  	}
   218  	b.SetBytes(int64(len(result)))
   219  
   220  	// Start the benchmark
   221  	b.ResetTimer()
   222  	b.ReportAllocs()
   223  	b.RunParallel(func(pb *testing.PB) {
   224  		for pb.Next() {
   225  			if _, err := Marshal(obj); err != nil {
   226  				b.Errorf("error marshaling YAML: %v", err)
   227  			}
   228  		}
   229  	})
   230  }
   231  
   232  func BenchmarkUnmarshal(b *testing.B) {
   233  	// Setup
   234  	yamlBytes, err := newBenchmarkYAML()
   235  	if err != nil {
   236  		b.Fatalf("error initializing YAML: %v", err)
   237  	}
   238  
   239  	// Record the number of bytes per operation
   240  	b.SetBytes(int64(len(yamlBytes)))
   241  
   242  	// Start the benchmark
   243  	b.ResetTimer()
   244  	b.ReportAllocs()
   245  	b.RunParallel(func(pb *testing.PB) {
   246  		for pb.Next() {
   247  			var result interface{}
   248  			if err = Unmarshal(yamlBytes, &result); err != nil {
   249  				b.Errorf("error unmarshaling YAML: %v", err)
   250  			}
   251  		}
   252  	})
   253  }
   254  
   255  func BenchmarkUnmarshalStrict(b *testing.B) {
   256  	// Setup
   257  	yamlBytes, err := newBenchmarkYAML()
   258  	if err != nil {
   259  		b.Fatalf("error initializing YAML: %v", err)
   260  	}
   261  
   262  	// Record the number of bytes per operation
   263  	b.SetBytes(int64(len(yamlBytes)))
   264  
   265  	// Start the benchmark
   266  	b.ResetTimer()
   267  	b.ReportAllocs()
   268  	b.RunParallel(func(pb *testing.PB) {
   269  		for pb.Next() {
   270  			var result interface{}
   271  			if err = UnmarshalStrict(yamlBytes, &result); err != nil {
   272  				b.Errorf("error unmarshaling YAML (Strict): %v", err)
   273  			}
   274  		}
   275  	})
   276  }
   277  
   278  func BenchmarkJSONToYAML(b *testing.B) {
   279  	// Setup
   280  	yamlBytes, err := newBenchmarkYAML()
   281  	if err != nil {
   282  		b.Fatalf("error initializing YAML: %v", err)
   283  	}
   284  	jsonBytes, err := YAMLToJSON(yamlBytes)
   285  	if err != nil {
   286  		b.Fatalf("error initializing JSON: %v", err)
   287  	}
   288  
   289  	// Record the number of bytes per operation
   290  	result, err := JSONToYAML(jsonBytes)
   291  	if err != nil {
   292  		b.Errorf("error converting JSON to YAML: %v", err)
   293  	}
   294  	b.SetBytes(int64(len(result)))
   295  
   296  	// Start the benchmark
   297  	b.ResetTimer()
   298  	b.ReportAllocs()
   299  	b.RunParallel(func(pb *testing.PB) {
   300  		for pb.Next() {
   301  			if _, err := JSONToYAML(jsonBytes); err != nil {
   302  				b.Errorf("error converting JSON to YAML: %v", err)
   303  			}
   304  		}
   305  	})
   306  }
   307  
   308  func BenchmarkYAMLtoJSON(b *testing.B) {
   309  	// Setup
   310  	yamlBytes, err := newBenchmarkYAML()
   311  	if err != nil {
   312  		b.Fatalf("error initializing YAML: %v", err)
   313  	}
   314  
   315  	// Record the number of bytes per operation
   316  	result, err := YAMLToJSON(yamlBytes)
   317  	if err != nil {
   318  		b.Errorf("error converting YAML to JSON: %v", err)
   319  	}
   320  	b.SetBytes(int64(len(result)))
   321  
   322  	// Start the benchmark
   323  	b.ResetTimer()
   324  	b.ReportAllocs()
   325  	b.RunParallel(func(pb *testing.PB) {
   326  		for pb.Next() {
   327  			if _, err := YAMLToJSON(yamlBytes); err != nil {
   328  				b.Errorf("error converting YAML to JSON: %v", err)
   329  			}
   330  		}
   331  	})
   332  }
   333  
   334  func BenchmarkYAMLtoJSONStrict(b *testing.B) {
   335  	// Setup
   336  	yamlBytes, err := newBenchmarkYAML()
   337  	if err != nil {
   338  		b.Fatalf("error initializing YAML: %v", err)
   339  	}
   340  
   341  	// Record the number of bytes per operation
   342  	result, err := YAMLToJSONStrict(yamlBytes)
   343  	if err != nil {
   344  		b.Errorf("error converting YAML to JSON (Strict): %v", err)
   345  	}
   346  	b.SetBytes(int64(len(result)))
   347  
   348  	// Start the benchmark
   349  	b.ResetTimer()
   350  	b.ReportAllocs()
   351  	b.RunParallel(func(pb *testing.PB) {
   352  		for pb.Next() {
   353  			if _, err := YAMLToJSONStrict(yamlBytes); err != nil {
   354  				b.Errorf("error converting YAML to JSON (Strict): %v", err)
   355  			}
   356  		}
   357  	})
   358  }
   359  
   360  func BenchmarkJSONObjectToYAMLObject(b *testing.B) {
   361  	// Setup
   362  	yamlBytes, err := newBenchmarkYAML()
   363  	if err != nil {
   364  		b.Fatalf("error initializing YAML: %v", err)
   365  	}
   366  	jsonBytes, err := YAMLToJSON(yamlBytes)
   367  	if err != nil {
   368  		b.Fatalf("error initializing JSON: %v", err)
   369  	}
   370  	var m map[string]interface{}
   371  	err = json.Unmarshal(jsonBytes, &m)
   372  	if err != nil {
   373  		b.Fatalf("error initializing map: %v", err)
   374  	}
   375  
   376  	// Start the benchmark
   377  	b.ResetTimer()
   378  	b.ReportAllocs()
   379  	b.RunParallel(func(pb *testing.PB) {
   380  		for pb.Next() {
   381  			JSONObjectToYAMLObject(m)
   382  		}
   383  	})
   384  }
   385  

View as plain text