New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: faster implementation of KObj #261
Conversation
Creating a KObjectReference creates work (allocation, string copy) that might not be needed when the log message is not actually emitted. An alternative implementation where KObj2 just keeps the interface and calls its only when needed is usually faster.
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: pohly The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
I'm just sharing to document the alternative approach. I'm not sure whether adding it to the klog API now is still worthwhile. It cannot replace the existing |
make sense to me. leaving review to sig-instrumentation. |
Recommend using https://github.com/golang/perf/tree/master/cmd/benchstat when analysing performance improvements in golang. This article explains why and how to use it https://about.sourcegraph.com/go/gophercon-2019-optimizing-go-code-without-a-blindfold/#Benchmarks-3-Statistics |
"benchstat" is indeed useful. I reorganized the benchmark so that it just has cases with I also included zapr. Here the results, including allocs (via
|
return ObjectRef2{KMetadata: obj} | ||
} | ||
|
||
type ObjectRef2 struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ObjectRef is expected to serialized to both text (using Stringer interface) and json (using Marshaler interface). ObjectRef annotates fields and uses default json marshaller. For ObjectRef2 we need to implement our own MarshalJSON
method.
Can you add MarshalJSON
to KObj2 and also benchmark it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ObjectRef is expected to serialized to both text (using Stringer interface) and json (using Marshaler interface).
That doesn't work for json. Zap prefers the String method over MarshalJSON over marshalling structs, see my comment in #240 (comment)
There are no test cases with KObj
in https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/component-base/logs/json/klog_test.go which might explain why this hasn't shown up before.
Can you add MarshalJSON to KObj2 and also benchmark it?
I already did that in the https://github.com/pohly/klog/commits/testinglogger-kobj2 branch that I used for benchmarking, but because it never gets called, it didn't make a difference (I also ran that comparison as benchmark, just to be sure).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's discuss the desired output for KObj in kubernetes/kubernetes#104877
@pohly: PR needs rebase. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
/close I'll come back to this as part of kubernetes/enhancements#3078. I've created a tracking issue at kubernetes/kubernetes#106945 |
@pohly: Closed this PR. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
What this PR does / why we need it:
KObj
always does some work (constructObjectReference
) which might not be needed later on and also is more expensive to copy.An alternative implementation (tentatively called
KObj2
at the moment) just stores the interface and uses it later on demand.Special notes for your reviewer:
When testing with
v1.Pod
, the benchmark gives:The commit which adds testing with
v1.Pod
shouldn't be merged because we probably don't want to depend on the k8s API. But it's more realistic than the benchmark with a fake object from the first commit, although that also shows an advantage.Release note:
TBD