mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-06 16:06:51 +00:00
Avoid allocations and a reflect.Call in conversion
reflect.Call is fairly expensive, performing 8 allocations and having to set up a call stack. Using a fairly straightforward to generate switch statement, we can bypass that early in conversion (as long as the function takes responsibility for invocation). We may also be able to avoid an allocation for the conversion scope, but not positive yet. ``` benchmark old ns/op new ns/op delta BenchmarkPodConversion-8 14713 12173 -17.26% benchmark old allocs new allocs delta BenchmarkPodConversion-8 80 72 -10.00% benchmark old bytes new bytes delta BenchmarkPodConversion-8 9133 8712 -4.61% ```
This commit is contained in:
@@ -29,6 +29,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/v1"
|
||||
"k8s.io/kubernetes/pkg/apimachinery"
|
||||
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||
"k8s.io/kubernetes/pkg/conversion"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util/sets"
|
||||
)
|
||||
@@ -150,4 +151,89 @@ func addVersionsToScheme(externalVersions ...unversioned.GroupVersion) {
|
||||
v1.AddToScheme(api.Scheme)
|
||||
}
|
||||
}
|
||||
|
||||
// This is a "fast-path" that avoids reflection for common types. It focuses on the objects that are
|
||||
// converted the most in the cluster.
|
||||
// TODO: generate one of these for every external API group - this is to prove the impact
|
||||
api.Scheme.AddGenericConversionFunc(func(objA, objB interface{}, s conversion.Scope) (bool, error) {
|
||||
switch a := objA.(type) {
|
||||
case *v1.Pod:
|
||||
switch b := objB.(type) {
|
||||
case *api.Pod:
|
||||
return true, v1.Convert_v1_Pod_To_api_Pod(a, b, s)
|
||||
}
|
||||
case *api.Pod:
|
||||
switch b := objB.(type) {
|
||||
case *v1.Pod:
|
||||
return true, v1.Convert_api_Pod_To_v1_Pod(a, b, s)
|
||||
}
|
||||
|
||||
case *v1.Event:
|
||||
switch b := objB.(type) {
|
||||
case *api.Event:
|
||||
return true, v1.Convert_v1_Event_To_api_Event(a, b, s)
|
||||
}
|
||||
case *api.Event:
|
||||
switch b := objB.(type) {
|
||||
case *v1.Event:
|
||||
return true, v1.Convert_api_Event_To_v1_Event(a, b, s)
|
||||
}
|
||||
|
||||
case *v1.ReplicationController:
|
||||
switch b := objB.(type) {
|
||||
case *api.ReplicationController:
|
||||
return true, v1.Convert_v1_ReplicationController_To_api_ReplicationController(a, b, s)
|
||||
}
|
||||
case *api.ReplicationController:
|
||||
switch b := objB.(type) {
|
||||
case *v1.ReplicationController:
|
||||
return true, v1.Convert_api_ReplicationController_To_v1_ReplicationController(a, b, s)
|
||||
}
|
||||
|
||||
case *v1.Node:
|
||||
switch b := objB.(type) {
|
||||
case *api.Node:
|
||||
return true, v1.Convert_v1_Node_To_api_Node(a, b, s)
|
||||
}
|
||||
case *api.Node:
|
||||
switch b := objB.(type) {
|
||||
case *v1.Node:
|
||||
return true, v1.Convert_api_Node_To_v1_Node(a, b, s)
|
||||
}
|
||||
|
||||
case *v1.Namespace:
|
||||
switch b := objB.(type) {
|
||||
case *api.Namespace:
|
||||
return true, v1.Convert_v1_Namespace_To_api_Namespace(a, b, s)
|
||||
}
|
||||
case *api.Namespace:
|
||||
switch b := objB.(type) {
|
||||
case *v1.Namespace:
|
||||
return true, v1.Convert_api_Namespace_To_v1_Namespace(a, b, s)
|
||||
}
|
||||
|
||||
case *v1.Service:
|
||||
switch b := objB.(type) {
|
||||
case *api.Service:
|
||||
return true, v1.Convert_v1_Service_To_api_Service(a, b, s)
|
||||
}
|
||||
case *api.Service:
|
||||
switch b := objB.(type) {
|
||||
case *v1.Service:
|
||||
return true, v1.Convert_api_Service_To_v1_Service(a, b, s)
|
||||
}
|
||||
|
||||
case *v1.Endpoints:
|
||||
switch b := objB.(type) {
|
||||
case *api.Endpoints:
|
||||
return true, v1.Convert_v1_Endpoints_To_api_Endpoints(a, b, s)
|
||||
}
|
||||
case *api.Endpoints:
|
||||
switch b := objB.(type) {
|
||||
case *v1.Endpoints:
|
||||
return true, v1.Convert_api_Endpoints_To_v1_Endpoints(a, b, s)
|
||||
}
|
||||
}
|
||||
return false, nil
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user