mirror of
https://github.com/kubernetes/client-go.git
synced 2026-07-16 17:14:36 +00:00
client-go watch: implement interface with pointer
I wasn't entirely sure whether this should return a value or a pointer to
satisfy the interface. Both works, so I benchmarked it elsewhere (REST
mapper). Mem allocs are the same (one alloc/call), but returning a value is 10%
slower when calling one method.
What I then benchmarked is whether pointer vs value receiver in the wrapper
makes a difference. Converting from value receiver (what I had before) to
pointer receiver reduced call overhead by 6%. That's because with a value
receiver, Go has to auto-generate a variant with pointer receiver and calls the
value receiver through that.
That can be seen in a debugger (call stack) and when setting breakpoints:
(dlv) b restMapperWrapper.KindForWithContext
Command failed: Location "restMapperWrapper.KindForWithContext" ambiguous: k8s.io/apimachinery/pkg/api/meta.restMapperWrapper.KindForWithContext, k8s.io/apimachinery/pkg/api/meta.(*restMapperWrapper).KindForWithContext…
Conventional wisdom is to define types with value receiver because those can be
called also on unmutable instances, making them more flexible.
But for types which will only ever be used via a pointer, I think pointer
receiver is better for the reasons above (small performance difference, easier
to debug).
Kubernetes-commit: b21dcbcaa1ccf4995bf486afc37dc0321c5bdf0b
This commit is contained in:
committed by
Kubernetes Publisher
parent
934ba1dfa5
commit
d7581d0654
6
tools/cache/listwatch.go
vendored
6
tools/cache/listwatch.go
vendored
@@ -90,7 +90,7 @@ func ToWatcherWithContext(w Watcher) WatcherWithContext {
|
||||
if w, ok := w.(WatcherWithContext); ok {
|
||||
return w
|
||||
}
|
||||
return watcherWrapper{
|
||||
return &watcherWrapper{
|
||||
parent: w,
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,7 @@ type watcherWrapper struct {
|
||||
parent Watcher
|
||||
}
|
||||
|
||||
func (l watcherWrapper) WatchWithContext(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) {
|
||||
func (l *watcherWrapper) WatchWithContext(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) {
|
||||
return l.parent.Watch(options)
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ func ToListerWatcherWithContext(lw ListerWatcher) ListerWatcherWithContext {
|
||||
if lw, ok := lw.(ListerWatcherWithContext); ok {
|
||||
return lw
|
||||
}
|
||||
return listerWatcherWrapper{
|
||||
return &listerWatcherWrapper{
|
||||
ListerWithContext: ToListerWithContext(lw),
|
||||
WatcherWithContext: ToWatcherWithContext(lw),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user